+++++++++++++++++++++++++++++++++++++++++++++++++
 The Boost Parameter Library 
+++++++++++++++++++++++++++++++++++++++++++++++++

|(logo)|__

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

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

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

:Abstract: Use this library to write functions and class templates
  that can accept arguments by name:

  .. parsed-literal::

    new_window("alert", **_width=10**, **_titlebar=false**);

    smart_ptr<
       Foo 
     , **deleter<Deallocate<Foo> >**
     , **copy_policy<DeepCopy>** > p(new Foo);
    
  Since named arguments can be passed in any order, they are
  especially useful when a function or template has more than one
  parameter with a useful default value.  The library also supports
  *deduced* parameters; that is to say, parameters whose identity
  can be deduced from their types.

.. @jam_prefix.append('''
        project test : requirements <include>. <source>/boost//headers ;''')

.. @example.prepend('''
   #include <boost/parameter.hpp>
   
   namespace test
   {
     BOOST_PARAMETER_NAME(title)
     BOOST_PARAMETER_NAME(width)
     BOOST_PARAMETER_NAME(titlebar)
   
     BOOST_PARAMETER_FUNCTION(
        (int), new_window, tag, (required (title,*)(width,*)(titlebar,*)))
     {
        return 0;
     }
     
     BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter)
     BOOST_PARAMETER_TEMPLATE_KEYWORD(copy_policy)

     template <class T> struct Deallocate {};
     struct DeepCopy {};

     namespace parameter = boost::parameter;
     
     struct Foo {};
     template <class T, class A0, class A1>
     struct smart_ptr
     {
         smart_ptr(Foo*);
     };
   }
   using namespace test;
   int x = ''');

.. @test('compile')


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

:Authors:       David Abrahams, Daniel Wallin
:Contact:       dave@boost-consulting.com, daniel@boostpro.com
:organization:  `BoostPro Computing`_
:date:          $Date: 2005/07/17 19:53:01 $

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

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

.. _concepts: http://www.boost.org/more/generic_programming.html#concept

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

[Note: this tutorial does not cover all details of the library.  Please see also the `reference documentation`__\ ]

__ reference.html

.. contents:: **Table of Contents**
   :depth: 2

.. role:: concept
   :class: concept

.. role:: vellipsis
   :class: vellipsis

.. section-numbering::

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

============
 Motivation
============

In C++, arguments_ are normally given meaning by their positions
with respect to a parameter_ list: the first argument passed maps
onto the first parameter in a function's definition, and so on.
That protocol is fine when there is at most one parameter with a
default value, but when there are even a few useful defaults, the
positional interface becomes burdensome:

* .. compound::

    Since an argument's meaning is given by its position, we have to
    choose an (often arbitrary) order for parameters with default
    values, making some combinations of defaults unusable:

    .. parsed-literal::

      window* new_window(
         char const* name, 
         **int border_width = default_border_width,**
         bool movable = true,
         bool initially_visible = true
         );

      const bool movability = false;
      window* w = new_window("alert box", movability);

    In the example above we wanted to make an unmoveable window
    with a default ``border_width``, but instead we got a moveable
    window with a ``border_width`` of zero.  To get the desired
    effect, we'd need to write:

    .. parsed-literal::

       window* w = new_window(
          "alert box", **default_border_width**, movability);

* .. compound::

    It can become difficult for readers to understand the meaning of
    arguments at the call site::

      window* w = new_window("alert", 1, true, false);

    Is this window moveable and initially invisible, or unmoveable
    and initially visible?  The reader needs to remember the order
    of arguments to be sure.  

* The author of the call may not remember the order of the
  arguments either, leading to hard-to-find bugs.

.. @ignore(3)

-------------------------
Named Function Parameters
-------------------------

.. compound::

  This library addresses the problems outlined above by associating
  each parameter name with a keyword object.  Now users can identify
  arguments by name, rather than by position:

  .. parsed-literal::

    window* w = new_window("alert box", **movable_=**\ false); // OK!

.. @ignore()

---------------------------
Deduced Function Parameters
---------------------------

.. compound::

  A **deduced parameter** can be passed in any position *without*
  supplying an explicit parameter name.  It's not uncommon for a
  function to have parameters that can be uniquely identified based
  on the types of arguments passed.  The ``name`` parameter to
  ``new_window`` is one such example.  None of the other arguments,
  if valid, can reasonably be converted to a ``char const*``.  With
  a deduced parameter interface, we could pass the window name in
  *any* argument position without causing ambiguity:

  .. parsed-literal::

    window* w = new_window(movable_=false, **"alert box"**); // OK!
    window* w = new_window(**"alert box"**, movable_=false); // OK!

  Appropriately used, a deduced parameter interface can free the
  user of the burden of even remembering the formal parameter
  names.

.. @ignore()

--------------------------------
Class Template Parameter Support
--------------------------------

.. compound::

  The reasoning we've given for named and deduced parameter
  interfaces applies equally well to class templates as it does to
  functions.  Using the Parameter library, we can create interfaces
  that allow template arguments (in this case ``shared`` and
  ``Client``) to be explicitly named, like this:

  .. parsed-literal::

    smart_ptr<**ownership<shared>**, **value_type<Client>** > p;

  The syntax for passing named template arguments is not quite as
  natural as it is for function arguments (ideally, we'd be able to
  write ``smart_ptr<ownership=shared,…>``).  This small syntactic
  deficiency makes deduced parameters an especially big win when
  used with class templates:

  .. parsed-literal::

    // *p and q could be equivalent, given a deduced*
    // *parameter interface.*
    smart_ptr<**shared**, **Client**> p;
    smart_ptr<**Client**, **shared**> q;

.. @ignore(2)

==========
 Tutorial
==========

This tutorial shows all the basics—how to build both named- and deduced-parameter
interfaces to function templates and class templates—and several
more advanced idioms as well.

---------------------------
Parameter-Enabled Functions
---------------------------

In this section we'll show how the Parameter library can be used to
build an expressive interface to the `Boost Graph library`__\ 's
|dfs|_ algorithm. [#old_interface]_ 

.. Revisit this

  After laying some groundwork
  and describing the algorithm's abstract interface, we'll show you
  how to build a basic implementation with keyword support.  Then
  we'll add support for default arguments and we'll gradually refine the
  implementation with syntax improvements.  Finally we'll show how to
  streamline the implementation of named parameter interfaces,
  improve their participation in overload resolution, and optimize
  their runtime efficiency.

__ ../../../graph/index.html

.. _dfs: ../../../graph/doc/depth_first_search.html

.. |dfs| replace:: ``depth_first_search``


Headers And Namespaces
======================

Most components of the Parameter library are declared in a
header named for the component.  For example, ::

  #include <boost/parameter/keyword.hpp>

will ensure ``boost::parameter::keyword`` is known to the
compiler.  There is also a combined header,
``boost/parameter.hpp``, that includes most of the library's
components.  For the the rest of this tutorial, unless we say
otherwise, you can use the rule above to figure out which header
to ``#include`` to access any given component of the library.

.. @example.append('''
   using boost::parameter::keyword;
   ''')

.. @test('compile')

Also, the examples below will also be written as if the
namespace alias ::

  namespace parameter = boost::parameter;

.. @ignore()

has been declared: we'll write ``parameter::xxx`` instead of
``boost::parameter::xxx``.

The Abstract Interface to |dfs|
===============================

The Graph library's |dfs| algorithm is a generic function accepting
from one to four arguments by reference.  If all arguments were
required, its signature might be as follows::

   template <
       class Graph, class DFSVisitor, class Index, class ColorMap
   >
   void depth_first_search(
     , Graph const& graph 
     , DFSVisitor visitor
     , typename graph_traits<g>::vertex_descriptor root_vertex
     , IndexMap index_map
     , ColorMap& color);

.. @ignore()

However, most of the parameters have a useful default value, as
shown in the table below.

.. _`parameter table`: 
.. _`default expressions`: 

.. table:: ``depth_first_search`` Parameters

  +----------------+----------+---------------------------------+----------------------------------+
  | Parameter Name | Dataflow | Type                            | Default Value (if any)           |
  +================+==========+=================================+==================================+
  |``graph``       | in       |Model of |IncidenceGraph|_ and   |none - this argument is required. |
  |                |          ||VertexListGraph|_               |                                  |
  |                |          |                                 |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``visitor``     | in       |Model of |DFSVisitor|_           |``boost::dfs_visitor<>()``        |
  +----------------+----------+---------------------------------+----------------------------------+
  |``root_vertex`` | in       |``graph``'s vertex descriptor    |``*vertices(graph).first``        |
  |                |          |type.                            |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``index_map``   | in       |Model of |ReadablePropertyMap|_  |``get(boost::vertex_index,graph)``|
  |                |          |with key type := ``graph``'s     |                                  |
  |                |          |vertex descriptor and value type |                                  |
  |                |          |an integer type.                 |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``color_map``   | in/out   |Model of |ReadWritePropertyMap|_ |an ``iterator_property_map``      |
  |                |          |with key type := ``graph``'s     |created from a ``std::vector`` of |
  |                |          |vertex descriptor type.          |``default_color_type`` of size    |
  |                |          |                                 |``num_vertices(graph)`` and using |
  |                |          |                                 |``index_map`` for the index map.  |
  +----------------+----------+---------------------------------+----------------------------------+

.. |IncidenceGraph| replace:: :concept:`Incidence Graph`
.. |VertexListGraph| replace:: :concept:`Vertex List Graph`
.. |DFSVisitor| replace:: :concept:`DFS Visitor`
.. |ReadablePropertyMap| replace:: :concept:`Readable Property Map`
.. |ReadWritePropertyMap| replace:: :concept:`Read/Write Property Map`

.. _`IncidenceGraph`: ../../../graph/doc/IncidenceGraph.html
.. _`VertexListGraph`: ../../../graph/doc/VertexListGraph.html
.. _`DFSVisitor`: ../../../graph/doc/DFSVisitor.html
.. _`ReadWritePropertyMap`: ../../../property_map/doc/ReadWritePropertyMap.html
.. _`ReadablePropertyMap`: ../../../property_map/doc/ReadablePropertyMap.html

Don't be intimidated by the information in the second and third
columns above.  For the purposes of this exercise, you don't need
to understand them in detail.

Defining the Keywords
=====================

The point of this exercise is to make it possible to call
``depth_first_search`` with named arguments, leaving out any
arguments for which the default is appropriate:

.. parsed-literal::

  graphs::depth_first_search(g, **color_map_=my_color_map**);

.. @ignore()

To make that syntax legal, there needs to be an object called
“\ ``color_map_``\ ” whose assignment operator can accept a
``my_color_map`` argument.  In this step we'll create one such
**keyword object** for each parameter.  Each keyword object will be
identified by a unique **keyword tag type**.  

.. Revisit this

  We're going to define our interface in namespace ``graphs``.  Since
  users need access to the keyword objects, but not the tag types,
  we'll define the keyword objects so they're accessible through
  ``graphs``, and we'll hide the tag types away in a nested
  namespace, ``graphs::tag``.  The library provides a convenient
  macro for that purpose.

We're going to define our interface in namespace ``graphs``.  The
library provides a convenient macro for defining keyword objects::

  #include <boost/parameter/name.hpp>

  namespace graphs
  {
    BOOST_PARAMETER_NAME(graph)    // Note: no semicolon
    BOOST_PARAMETER_NAME(visitor)
    BOOST_PARAMETER_NAME(root_vertex)
    BOOST_PARAMETER_NAME(index_map)
    BOOST_PARAMETER_NAME(color_map)
  }

.. @test('compile')

The declaration of the ``graph`` keyword you see here is
equivalent to::

  namespace graphs 
  {
    namespace tag { struct graph; } // keyword tag type

    namespace // unnamed
    {
      // A reference to the keyword object
      boost::parameter::keyword<tag::graph>& _graph
      = boost::parameter::keyword<tag::graph>::get();
    }
  }

.. @example.prepend('#include <boost/parameter/keyword.hpp>')
.. @test('compile')

It defines a *keyword tag type* named ``tag::graph`` and a *keyword
object* reference named ``_graph``.

This “fancy dance” involving an unnamed namespace and references
is all done to avoid violating the One Definition Rule (ODR)
[#odr]_ when the named parameter interface is used by function
templates that are instantiated in multiple translation
units (MSVC6.x users see `this note`__).

__ `Compiler Can't See References In Unnamed Namespace`_

Writing the Function
====================

Now that we have our keywords defined, the function template
definition follows a simple pattern using the
``BOOST_PARAMETER_FUNCTION`` macro::

  #include <boost/parameter/preprocessor.hpp>

  namespace graphs
  {
    BOOST_PARAMETER_FUNCTION(
        (void),                // 1. parenthesized return type
        depth_first_search,    // 2. name of the function template

        tag,                   // 3. namespace of tag types

        (required (graph, *) ) // 4. one required parameter, and

        (optional              //    four optional parameters, with defaults
          (visitor,           *, boost::dfs_visitor<>()) 
          (root_vertex,       *, *vertices(graph).first) 
          (index_map,         *, get(boost::vertex_index,graph)) 
          (in_out(color_map), *, 
            default_color_map(num_vertices(graph), index_map) ) 
        )
    )
    {
        // ... body of function goes here...
        // use graph, visitor, index_map, and color_map
    }
  }

.. @example.prepend('''
   #include <boost/parameter/name.hpp>

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   namespace boost {

   template <class T = int>
   struct dfs_visitor
   {};

   int vertex_index = 0;

   }''')

.. @test('compile')

The arguments to ``BOOST_PARAMETER_FUNCTION`` are:

1. The return type of the resulting function template.  Parentheses
   around the return type prevent any commas it might contain from
   confusing the preprocessor, and are always required.

2. The name of the resulting function template.

3. The name of a namespace where we can find tag types whose names
   match the function's parameter names.

4. The function signature.  

Function Signatures
===================

Function signatures are described as one or two adjacent
parenthesized terms (a Boost.Preprocessor_ sequence_) describing
the function's parameters in the order in which they'd be expected
if passed positionally.  Any required parameters must come first,
but the ``(required … )`` clause can be omitted when all the
parameters are optional.

.. _Boost.Preprocessor: ../../../preprocessor/index.html

Required Parameters
-------------------

.. compound::

  Required parameters are given first—nested in a ``(required … )``
  clause—as a series of two-element tuples describing each parameter
  name and any requirements on the argument type.  In this case there
  is only a single required parameter, so there's just a single
  tuple:

  .. parsed-literal::

     (required **(graph, \*)** )

  Since ``depth_first_search`` doesn't require any particular type
  for its ``graph`` parameter, we use an asterix to indicate that
  any type is allowed.  Required parameters must always precede any
  optional parameters in a signature, but if there are *no*
  required parameters, the ``(required … )`` clause can be omitted
  entirely.

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(graph)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
   ''')

.. @example.append(') {}')
.. @test('compile')

Optional Parameters
-------------------

.. compound::

  Optional parameters—nested in an ``(optional … )`` clause—are given
  as a series of adjacent *three*\ -element tuples describing the
  parameter name, any requirements on the argument type, *and* and an
  expression representing the parameter's default value:

  .. parsed-literal::

    (optional **\
        (visitor,           \*, boost::dfs_visitor<>()) 
        (root_vertex,       \*, \*vertices(graph).first) 
        (index_map,         \*, get(boost::vertex_index,graph)) 
        (in_out(color_map), \*, 
          default_color_map(num_vertices(graph), index_map) )**
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   namespace boost
   {
     int vertex_index = 0;

     template <class T = int>
     struct dfs_visitor
     {};
   }

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
     (required (graph, *))
   ''')

.. @example.append(') {}')
.. @test('compile')

Handling “Out” Parameters
-------------------------

.. compound::

  Within the function body, a parameter name such as ``visitor`` is
  a *C++ reference*, bound either to an actual argument passed by
  the caller or to the result of evaluating a default expression.
  In most cases, parameter types are of the form ``T const&`` for
  some ``T``.  Parameters whose values are expected to be modified,
  however, must be passed by reference to *non*\ -``const``.  To
  indicate that ``color_map`` is both read and written, we wrap
  its name in ``in_out(…)``:

  .. parsed-literal::

    (optional
        (visitor,            \*, boost::dfs_visitor<>()) 
        (root_vertex,        \*, \*vertices(graph).first) 
        (index_map,          \*, get(boost::vertex_index,graph)) 
        (**in_out(color_map)**, \*, 
          default_color_map(num_vertices(graph), index_map) )
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   namespace boost
   {
     int vertex_index = 0;

     template <class T = int>
     struct dfs_visitor
     {};
   }

   BOOST_PARAMETER_NAME(graph)

   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
     (required (graph, *))
   ''')

.. @example.append(') {}')
.. @test('compile')

If ``color_map`` were strictly going to be modified but not examined,
we could have written ``out(color_map)``.  There is no functional
difference between ``out`` and ``in_out``; the library provides
both so you can make your interfaces more self-documenting.

Positional Arguments
--------------------

When arguments are passed positionally (without the use of
keywords), they will be mapped onto parameters in the order the
parameters are given in the signature, so for example in this
call ::

  graphs::depth_first_search(x, y);

.. @ignore()

``x`` will always be interpreted as a graph and ``y`` will always
be interpreted as a visitor.

.. _sequence: http://boost-consulting.com/mplbook/preprocessor.html#sequences

Default Expression Evaluation
-----------------------------

.. compound::

  Note that in our example, the value of the graph parameter is
  used in the default expressions for ``root_vertex``,
  ``index_map`` and ``color_map``.  

  .. parsed-literal::

        (required (**graph**, \*) )
        (optional
          (visitor,           \*, boost::dfs_visitor<>()) 
          (root_vertex,       \*, \*vertices(**graph**).first) 
          (index_map,         \*, get(boost::vertex_index,\ **graph**)) 
          (in_out(color_map), \*, 
            default_color_map(num_vertices(**graph**), index_map) ) 
        )

  .. @ignore()

  A default expression is evaluated in the context of all preceding
  parameters, so you can use any of their values by name.

.. compound::

  A default expression is never evaluated—or even instantiated—if
  an actual argument is passed for that parameter.  We can actually
  demonstrate that with our code so far by replacing the body of
  ``depth_first_search`` with something that prints the arguments:

  .. parsed-literal::

    #include <boost/graph/depth_first_search.hpp> // for dfs_visitor

    BOOST_PARAMETER_FUNCTION(
        (void), depth_first_search, tag
        *…signature goes here…*
    )
    {
       std::cout << "graph=" << graph << std::endl;
       std::cout << "visitor=" << visitor << std::endl;
       std::cout << "root_vertex=" << root_vertex << std::endl;
       std::cout << "index_map=" << index_map << std::endl;
       std::cout << "color_map=" << color_map << std::endl;
    }

    int main()
    {
        depth_first_search(1, 2, 3, 4, 5);

        depth_first_search(
            "1", '2', _color_map = '5',
            _index_map = "4", _root_vertex = "3");
    }

  Despite the fact that default expressions such as
  ``vertices(graph).first`` are ill-formed for the given ``graph``
  arguments, both calls will compile, and each one will print
  exactly the same thing.

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)''')

.. @example.replace_emphasis('''
   , (required 
       (graph, *)
       (visitor, *)
       (root_vertex, *)
       (index_map, *)
       (color_map, *)
     )
   ''')
.. @test('compile')

Signature Matching and Overloading
----------------------------------

In fact, the function signature is so general that any call to
``depth_first_search`` with fewer than five arguments will match
our function, provided we pass *something* for the required
``graph`` parameter.  That might not seem to be a problem at first;
after all, if the arguments don't match the requirements imposed by
the implementation of ``depth_first_search``, a compilation error
will occur later, when its body is instantiated.

There are at least three problems with very general function
signatures.  

1. By the time our ``depth_first_search`` is instantiated, it has
   been selected as the best matching overload.  Some other
   ``depth_first_search`` overload might've worked had it been
   chosen instead.  By the time we see a compilation error, there's
   no chance to change that decision.

2. Even if there are no overloads, error messages generated at
   instantiation time usually expose users to confusing
   implementation details.  For example, users might see references
   to names generated by ``BOOST_PARAMETER_FUNCTION`` such as
   ``graphs::detail::depth_first_search_with_named_params`` (or
   worse—think of the kinds of errors you get from your STL
   implementation when you make a mistake). [#ConceptCpp]_

3. The problems with exposing such permissive function template
   signatures have been the subject of much discussion, especially
   in the presence of `unqualified calls`__.  If all we want is to
   avoid unintentional argument-dependent lookup (ADL), we can
   isolate ``depth_first_search`` in a namespace containing no
   types [#using]_, but suppose we *want* it to found via ADL?

__ http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#225

It's usually a good idea to prevent functions from being considered
for overload resolution when the passed argument types aren't
appropriate.  The library already does this when the required
``graph`` parameter is not supplied, but we're not likely to see a
depth first search that doesn't take a graph to operate on.
Suppose, instead, that we found a different depth first search
algorithm that could work on graphs that don't model
|IncidenceGraph|_?  If we just added a simple overload,
it would be ambiguous::

  // new overload
  BOOST_PARAMETER_FUNCTION(
      (void), depth_first_search, (tag), (required (graph,*))( … ))
  {
      // new algorithm implementation
  }

  …

  // ambiguous!
  depth_first_search(boost::adjacency_list<>(), 2, "hello");

.. @ignore()

Adding Type Requirements
........................

We really don't want the compiler to consider the original version
of ``depth_first_search`` because the ``root_vertex`` argument,
``"hello"``, doesn't meet the requirement__ that it match the
``graph`` parameter's vertex descriptor type.  Instead, this call
should just invoke our new overload.  To take the original
``depth_first_search`` overload out of contention, we need to tell
the library about this requirement by replacing the ``*`` element
of the signature with the required type, in parentheses:

__ `parameter table`_

.. parsed-literal::

  (root_vertex,       
       **(typename boost::graph_traits<graph_type>::vertex_descriptor)**,
       \*vertices(graph).first) 

.. @ignore()

Now the original ``depth_first_search`` will only be called when
the ``root_vertex`` argument can be converted to the graph's vertex
descriptor type, and our example that *was* ambiguous will smoothly
call the new overload.

.. Note:: The *type* of the ``graph`` argument is available in the
   signature—and in the function body—as ``graph_type``.  In
   general, to access the type of any parameter *foo*, write *foo*\
   ``_type``.


Predicate Requirements
......................

The requirements on other arguments are a bit more interesting than
those on ``root_vertex``; they can't be described in terms of simple
type matching.  Instead, they must be described in terms of `MPL
Metafunctions`__.  There's no space to give a complete description
of metafunctions or of graph library details here, but we'll show
you the complete signature with maximal checking, just to give you
a feel for how it's done.  Each predicate metafunction is enclosed
in parentheses *and preceded by an asterix*, as follows:

.. parsed-literal::

    BOOST_PARAMETER_FUNCTION(
        (void), depth_first_search, graphs

      , (required 
          (graph 
           , **\ \*(boost::mpl::and_<
                   boost::is_convertible<
                       boost::graph_traits<_>::traversal_category
                     , boost::incidence_graph_tag
                   >
                 , boost::is_convertible<
                       boost::graph_traits<_>::traversal_category
                     , boost::vertex_list_graph_tag
                   >
               >)** ))

        (optional
          (visitor, \*, boost::dfs_visitor<>()) // not checkable

          (root_vertex
            , (typename boost::graph_traits<graphs::graph::_>::vertex_descriptor)
            , \*vertices(graph).first)
 
          (index_map
            , **\ \*(boost::mpl::and_<
                  boost::is_integral<
                      boost::property_traits<_>::value_type
                  >
                , boost::is_same<
                      typename boost::graph_traits<graphs::graph::_>::vertex_descriptor
                    , boost::property_traits<_>::key_type
                  >
              >)**
            , get(boost::vertex_index,graph))
 
          (in_out(color_map)
            , **\ \*(boost::is_same<
                  typename boost::graph_traits<graphs::graph::_>::vertex_descriptor
                , boost::property_traits<_>::key_type
              >)**
           , default_color_map(num_vertices(graph), index_map) ) 
        )
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME((_graph, graphs) graph) 
   BOOST_PARAMETER_NAME((_visitor, graphs) visitor) 
   BOOST_PARAMETER_NAME((_root_vertex, graphs) root_vertex) 
   BOOST_PARAMETER_NAME((_index_map, graphs) index_map) 
   BOOST_PARAMETER_NAME((_color_map, graphs) color_map)

   using boost::mpl::_;

   namespace boost
   {
     struct incidence_graph_tag {};
     struct vertex_list_graph_tag {};

     int vertex_index = 0;

     template <class T>
     struct graph_traits
     {
         typedef int traversal_category;
         typedef int vertex_descriptor;
     };

     template <class T>
     struct property_traits
     {
         typedef int value_type;
         typedef int key_type;
     };

     template <class T = int>
     struct dfs_visitor 
     {};
   }''')

.. @example.append('''
   {}''')

.. @test('compile')

__ ../../../mpl/doc/refmanual/metafunction.html

We acknowledge that this signature is pretty hairy looking.
Fortunately, it usually isn't necessary to so completely encode the
type requirements on arguments to generic functions.  However, it
is usally worth the effort to do so: your code will be more
self-documenting and will often provide a better user experience.
You'll also have an easier transition to an upcoming C++ standard
with `language support for concepts`__.

__ `ConceptC++`_

Deduced Parameters
------------------

To illustrate deduced parameter support we'll have to leave behind
our example from the Graph library.  Instead, consider the example
of the |def|_ function from Boost.Python_.  Its signature is
roughly as follows::

  template <
    class Function, Class KeywordExpression, class CallPolicies
  >
  void def(
      // Required parameters
      char const* name, Function func

      // Optional, deduced parameters
    , char const* docstring = ""
    , KeywordExpression keywords = no_keywords()
    , CallPolicies policies = default_call_policies()
  );

.. @ignore()

Try not to be too distracted by the use of the term “keywords” in
this example: although it means something analogous in Boost.Python
to what it means in the Parameter library, for the purposes of this
exercise you can think of it as being completely different.

When calling ``def``, only two arguments are required.  The
association between any additional arguments and their parameters
can be determined by the types of the arguments actually passed, so
the caller is neither required to remember argument positions or
explicitly specify parameter names for those arguments.  To
generate this interface using ``BOOST_PARAMETER_FUNCTION``, we need
only enclose the deduced parameters in a ``(deduced …)`` clause, as
follows: 

.. parsed-literal::

  namespace mpl = boost::mpl;

  BOOST_PARAMETER_FUNCTION(
      (void), def, tag,

      (required (name,(char const\*)) (func,\*) )   // nondeduced

      **(deduced** 
        (optional 
          (docstring, (char const\*), "")

          (keywords
             , \*(is_keyword_expression<mpl::_>) // see [#is_keyword_expression]_
             , no_keywords())

          (policies
             , \*(mpl::not_<
                   mpl::or_<
                       boost::is_convertible<mpl::_, char const\*>
                     , is_keyword_expression<mpl::_> // see [#is_keyword_expression]_
                   >
               >)
             , default_call_policies()
           )
         )
       **)**
   )
   {
      *…*
   }

.. @example.replace_emphasis('')

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(name)
   BOOST_PARAMETER_NAME(func)
   BOOST_PARAMETER_NAME(docstring)
   BOOST_PARAMETER_NAME(keywords)
   BOOST_PARAMETER_NAME(policies)

   struct default_call_policies
   {};

   struct no_keywords
   {};

   struct keywords
   {};

   template <class T>
   struct is_keyword_expression
     : boost::mpl::false_
   {};

   template <>
   struct is_keyword_expression<keywords>
     : boost::mpl::true_
   {};

   default_call_policies some_policies;

   void f()
   {}

   ''')

.. Admonition:: Syntax Note

  A ``(deduced …)`` clause always contains a ``(required …)``
  and/or an ``(optional …)`` subclause, and must follow any
  ``(required …)`` or ``(optional …)`` clauses indicating
  nondeduced parameters at the outer level.

With the declaration above, the following two calls are equivalent:

.. parsed-literal::

  def("f", &f, **some_policies**, **"Documentation for f"**);
  def("f", &f, **"Documentation for f"**, **some_policies**);

.. @example.prepend('''
   int main()
   {''')

If the user wants to pass a ``policies`` argument that was also,
for some reason, convertible to ``char const*``, she can always
specify the parameter name explicitly, as follows:

.. parsed-literal::

  def(
      "f", &f
     , **_policies = some_policies**, "Documentation for f");

.. @example.append('}')
.. @test('compile', howmany='all')

.. _Boost.Python: ../../../python/doc/index.html
.. |def| replace:: ``def``
.. _def: ../../../python/doc/v2/def.html

----------------------------------
Parameter-Enabled Member Functions
----------------------------------


The ``BOOST_PARAMETER_MEMBER_FUNCTION`` and
``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros accept exactly the
same arguments as ``BOOST_PARAMETER_FUNCTION``, but are designed to
be used within the body of a class::

  BOOST_PARAMETER_NAME(arg1)
  BOOST_PARAMETER_NAME(arg2)

  struct callable2
  {
      BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
          (void), call, tag, (required (arg1,(int))(arg2,(int))))
      {
          std::cout << arg1 << ", " << arg2 << std::endl;
      }
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>
   using namespace boost::parameter;
   ''')

.. @test('compile')

These macros don't directly allow a function's interface to be
separated from its implementation, but you can always forward
arguments on to a separate implementation function::

  struct callable2
  {
      BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
          (void), call, tag, (required (arg1,(int))(arg2,(int))))
      {
          call_impl(arg1,arg2);
      }
   private:
      void call_impl(int, int); // implemented elsewhere.
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(arg1)
   BOOST_PARAMETER_NAME(arg2)
   using namespace boost::parameter;
   ''')

.. @test('compile')

Static Member Functions
=======================

To expose a static member function, simply insert the keyword
“``static``” before the function name:

.. parsed-literal::

  BOOST_PARAMETER_NAME(arg1)

  struct somebody
  {
      BOOST_PARAMETER_MEMBER_FUNCTION(
          (void), **static** f, tag, (optional (arg1,(int),0)))
      {
          std::cout << arg1 << std::endl;
      }
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>
   using namespace boost::parameter;
   ''')

.. @test('compile')


------------------------------
Parameter-Enabled Constructors
------------------------------

The lack of a “delegating constructor”
feature in C++
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf)
limits somewhat the quality of interface this library can provide
for defining parameter-enabled constructors.  The usual workaround
for a lack of constructor delegation applies: one must factor the
common logic into a base class.  

Let's build a parameter-enabled constructor that simply prints its
arguments.  The first step is to write a base class whose
constructor accepts a single argument known as an |ArgumentPack|_:
a bundle of references to the actual arguments, tagged with their
keywords.  The values of the actual arguments are extracted from
the |ArgumentPack| by *indexing* it with keyword objects::

  BOOST_PARAMETER_NAME(name)
  BOOST_PARAMETER_NAME(index)

  struct myclass_impl
  {
      template <class ArgumentPack>
      myclass_impl(ArgumentPack const& args)
      {
          std::cout << "name = " << args[_name] 
                    << "; index = " << args[_index | 42] 
                    << std::endl;
      }
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Note that the bitwise or (“\ ``|``\ ”) operator has a special
meaning when applied to keyword objects that are passed to an
|ArgumentPack|\ 's indexing operator: it is used to indicate a
default value.  In this case if there is no ``index`` parameter in
the |ArgumentPack|, ``42`` will be used instead.

Now we are ready to write the parameter-enabled constructor
interface::

  struct myclass : myclass_impl
  {
      BOOST_PARAMETER_CONSTRUCTOR(
          myclass, (myclass_impl), tag
        , (required (name,*)) (optional (index,*))) // no semicolon
  };

Since we have supplied a default value for ``index`` but not for
``name``, only ``name`` is required.  We can exercise our new
interface as follows::

  myclass x("bob", 3);                     // positional
  myclass y(_index = 12, _name = "sally"); // named
  myclass z("june");                       // positional/defaulted

.. @example.wrap('int main() {', '}')
.. @test('run', howmany='all')

For more on |ArgumentPack| manipulation, see the `Advanced Topics`_
section.

---------------------------------
Parameter-Enabled Class Templates
---------------------------------

In this section we'll use Boost.Parameter to build Boost.Python_\
's `class_`_ template, whose “signature” is:

.. parsed-literal::

  template class<
      ValueType, BaseList = bases<>
    , HeldType = ValueType, Copyable = void
  >
  class class\_;

.. @ignore()

Only the first argument, ``ValueType``, is required.

.. _class_: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec

Named Template Parameters
=========================

First, we'll build an interface that allows users to pass arguments
positionally or by name:

.. parsed-literal::

  struct B { virtual ~B() = 0; };
  struct D : B { ~D(); };

  class_<
       **class_type<B>**, **copyable<boost::noncopyable>** 
  > …;

  class_<
      **D**, **held_type<std::auto_ptr<D> >**, **base_list<bases<B> >**
  > …;

.. @ignore()

Template Keywords
-----------------

The first step is to define keywords for each template parameter::

  namespace boost { namespace python {

  BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @test('compile')

The declaration of the ``class_type`` keyword you see here is
equivalent to::

  namespace boost { namespace python {

  namespace tag { struct class_type; } // keyword tag type
  template <class T>
  struct class_type
    : parameter::template_keyword<tag::class_type,T>
  {};

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @test('compile')

It defines a keyword tag type named ``tag::class_type`` and a
*parameter passing template* named ``class_type``.

Class Template Skeleton
-----------------------

The next step is to define the skeleton of our class template,
which has three optional parameters.  Because the user may pass
arguments in any order, we don't know the actual identities of
these parameters, so it would be premature to use descriptive names
or write out the actual default values for any of them.  Instead,
we'll give them generic names and use the special type
``boost::parameter::void_`` as a default:

.. parsed-literal::

  namespace boost { namespace python {

  template <
      class A0
    , class A1 = parameter::void\_
    , class A2 = parameter::void\_
    , class A3 = parameter::void\_
  >
  struct class\_
  {
      *…*
  };

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @example.replace_emphasis('')
.. @test('compile')

Class Template Signatures
-------------------------

Next, we need to build a type, known as a |ParameterSpec|_,
describing the “signature” of ``boost::python::class_``.  A
|ParameterSpec|_ enumerates the required and optional parameters in
their positional order, along with any type requirements (note that
it does *not* specify defaults -- those will be dealt with
separately)::

  namespace boost { namespace python {

  using boost::mpl::_;

  typedef parameter::parameters<
      required<tag::class_type, boost::is_class<_> >
    , parameter::optional<tag::base_list, mpl::is_sequence<_> >
    , parameter::optional<tag::held_type>
    , parameter::optional<tag::copyable>
  > class_signature;

  }}

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/mpl/is_sequence.hpp>
   #include <boost/noncopyable.hpp>
   #include <boost/type_traits/is_class.hpp>
   #include <memory>

   using namespace boost::parameter;

   namespace boost { namespace python {

   BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

   template <class B = int>
   struct bases
   {};

   }}''')

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

.. _ParameterSpec: reference.html#parameterspec

.. _binding_intro:

Argument Packs and Parameter Extraction
---------------------------------------

Next, within the body of ``class_`` , we use the |ParameterSpec|\ 's
nested ``::bind< … >`` template to bundle the actual arguments into an
|ArgumentPack|_ type, and then use the library's ``value_type< … >``
metafunction to extract “logical parameters”.  ``value_type< … >`` is
a lot like ``binding< … >``, but no reference is added to the actual
argument type.  Note that defaults are specified by passing it an
optional third argument::

  namespace boost { namespace python {

  template <
      class A0
    , class A1 = parameter::void_
    , class A2 = parameter::void_
    , class A3 = parameter::void_
  >
  struct class_
  {
      // Create ArgumentPack
      typedef typename 
        class_signature::bind<A0,A1,A2,A3>::type 
      args;

      // Extract first logical parameter.
      typedef typename parameter::value_type<
        args, tag::class_type>::type class_type;
      
      typedef typename parameter::value_type<
        args, tag::base_list, bases<> >::type base_list;
      
      typedef typename parameter::value_type<
        args, tag::held_type, class_type>::type held_type;
      
      typedef typename parameter::value_type<
        args, tag::copyable, void>::type copyable;
  };

  }}

.. |ArgumentPack| replace:: :concept:`ArgumentPack`
.. _ArgumentPack: reference.html#argumentpack

Exercising the Code So Far
==========================

.. compound::

  Revisiting our original examples, ::

    typedef boost::python::class_<
        class_type<B>, copyable<boost::noncopyable> 
    > c1;

    typedef boost::python::class_<
        D, held_type<std::auto_ptr<D> >, base_list<bases<B> > 
    > c2;

  .. @example.prepend('''
     using boost::python::class_type;
     using boost::python::copyable;
     using boost::python::held_type;
     using boost::python::base_list;
     using boost::python::bases;

     struct B {};
     struct D {};''')

  we can now examine the intended parameters::

    BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
    BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
    BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
    BOOST_MPL_ASSERT((
         boost::is_same<c1::copyable, boost::noncopyable>
    ));

    BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
    BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
    BOOST_MPL_ASSERT((
        boost::is_same<c2::held_type, std::auto_ptr<D> >
    ));
    BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));

.. @test('compile', howmany='all')

Deduced Template Parameters
===========================

To apply a deduced parameter interface here, we need only make the
type requirements a bit tighter so the ``held_type`` and
``copyable`` parameters can be crisply distinguished from the
others.  Boost.Python_ does this by requiring that ``base_list`` be
a specialization of its ``bases< … >`` template (as opposed to
being any old MPL sequence) and by requiring that ``copyable``, if
explicitly supplied, be ``boost::noncopyable``.  One easy way of
identifying specializations of ``bases< … >`` is to derive them all
from the same class, as an implementation detail:

.. parsed-literal::

  namespace boost { namespace python {

  namespace detail { struct bases_base {}; }

  template <class A0 = void, class A1 = void, class A2 = void *…* >
  struct bases **: detail::bases_base**
  {};

  }}  

.. @example.replace_emphasis('')
.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/mpl/is_sequence.hpp>
   #include <boost/noncopyable.hpp>
   #include <memory>

   using namespace boost::parameter;
   using boost::mpl::_;

   namespace boost { namespace python {

   BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

   }}''')

Now we can rewrite our signature to make all three optional
parameters deducible::

  typedef parameter::parameters<
      required<tag::class_type, is_class<_> >

    , parameter::optional<
          deduced<tag::base_list>
        , is_base_and_derived<detail::bases_base,_>
      >

    , parameter::optional<
          deduced<tag::held_type>
        , mpl::not_<
              mpl::or_<
                  is_base_and_derived<detail::bases_base,_>
                , is_same<noncopyable,_>
              >
          >
      >

    , parameter::optional<deduced<tag::copyable>, is_same<noncopyable,_> >

  > class_signature;

.. @example.prepend('''
   #include <boost/type_traits/is_class.hpp>
   namespace boost { namespace python {''')

.. @example.append('''
   template <
       class A0
     , class A1 = parameter::void_
     , class A2 = parameter::void_
     , class A3 = parameter::void_
   >
   struct class_
   {
       // Create ArgumentPack
       typedef typename 
         class_signature::bind<A0,A1,A2,A3>::type 
       args;
 
       // Extract first logical parameter.
       typedef typename parameter::value_type<
         args, tag::class_type>::type class_type;
      
       typedef typename parameter::value_type<
         args, tag::base_list, bases<> >::type base_list;
      
       typedef typename parameter::value_type<
         args, tag::held_type, class_type>::type held_type;
      
       typedef typename parameter::value_type<
         args, tag::copyable, void>::type copyable;
   };

   }}''')

It may seem like we've added a great deal of complexity, but the
benefits to our users are greater.  Our original examples can now
be written without explicit parameter names:

.. parsed-literal::

  typedef boost::python::class_<**B**, **boost::noncopyable**> c1;

  typedef boost::python::class_<**D**, **std::auto_ptr<D>**, **bases<B>** > c2;

.. @example.prepend('''
   struct B {};
   struct D {};

   using boost::python::bases;''')

.. @example.append('''
   BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
   BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
   BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
   BOOST_MPL_ASSERT((
        boost::is_same<c1::copyable, boost::noncopyable>
   ));

   BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
   BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
   BOOST_MPL_ASSERT((
       boost::is_same<c2::held_type, std::auto_ptr<D> >
   ));
   BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));''')

.. @test('compile', howmany='all')

===============
Advanced Topics
===============

At this point, you should have a good grasp of the basics.  In this
section we'll cover some more esoteric uses of the library.

-------------------------
Fine-Grained Name Control
-------------------------

If you don't like the leading-underscore naming convention used
to refer to keyword objects, or you need the name ``tag`` for
something other than the keyword type namespace, there's another
way to use ``BOOST_PARAMETER_NAME``:

.. parsed-literal::

   BOOST_PARAMETER_NAME(\ **(**\ *object-name*\ **,** *tag-namespace*\ **)** *parameter-name*\ )

.. @ignore()

Here is a usage example:

.. parsed-literal::

  BOOST_PARAMETER_NAME((**pass_foo**, **keywords**) **foo**)

  BOOST_PARAMETER_FUNCTION(
    (int), f, 
    **keywords**, (required (**foo**, \*)))
  {
      return **foo** + 1;
  }

  int x = f(**pass_foo** = 41);

.. @example.prepend('#include <boost/parameter.hpp>')
.. @example.append('''
   int main()
   {}''')
.. @test('run')

Before you use this more verbose form, however, please read the
section on `best practices for keyword object naming`__.

__ `Keyword Naming`_

-----------------------
More |ArgumentPack|\ s
-----------------------

We've already seen |ArgumentPack|\ s when we looked at
`parameter-enabled constructors`_ and `class templates`__.  As you
might have guessed, |ArgumentPack|\ s actually lie at the heart of
everything this library does; in this section we'll examine ways to
build and manipulate them more effectively.

__ binding_intro_

Building |ArgumentPack|\ s
==========================

The simplest |ArgumentPack| is the result of assigning into a
keyword object::

   BOOST_PARAMETER_NAME(index)

   template <class ArgumentPack>
   int print_index(ArgumentPack const& args)
   {
       std::cout << "index = " << args[_index] << std::endl;
       return 0;
   }

   int x = print_index(_index = 3);  // prints "index = 3"

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Also, |ArgumentPack|\ s can be composed using the comma operator.
The extra parentheses below are used to prevent the compiler from
seeing two separate arguments to ``print_name_and_index``::

   BOOST_PARAMETER_NAME(name)

   template <class ArgumentPack>
   int print_name_and_index(ArgumentPack const& args)
   {
       std::cout << "name = " << args[_name] << "; ";
       return print_index(args);
   }

   int y = print_name_and_index((_index = 3, _name = "jones"));

To build an |ArgumentPack| with positional arguments, we can use a
|ParameterSpec|_.  As introduced described in the section on `Class
Template Signatures`_, a |ParameterSpec| describes the positional
order of parameters and any associated type requirements.  Just as
we can build an |ArgumentPack| *type* with its nested ``::bind< …
>`` template, we can build an |ArgumentPack| *object* by invoking
its function call operator:

.. parsed-literal::

  parameter::parameters<
      required<tag::\ name, is_convertible<_,char const*> >
    , optional<tag::\ index, is_convertible<_,int> >
  > spec;

  char const sam[] = "sam";
  int twelve = 12;

  int z0 = print_name_and_index( **spec(**\ sam, twelve\ **)** );

  int z1 = print_name_and_index( 
     **spec(**\ _index=12, _name="sam"\ **)** 
  );

.. @example.prepend('''
   namespace parameter = boost::parameter;
   using parameter::required;
   using parameter::optional;
   using boost::is_convertible;
   using boost::mpl::_;''')

.. @example.append('''
   int main()
   {}''')

.. @test('run', howmany='all')

Note that because of the `forwarding problem`_, ``parameter::parameters::operator()``
can't accept non-const rvalues.

.. _`forwarding problem`: http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

Extracting Parameter Types
==========================

If we want to know the types of the arguments passed to
``print_name_and_index``, we have a couple of options.  The
simplest and least error-prone approach is to forward them to a
function template and allow *it* to do type deduction::

   BOOST_PARAMETER_NAME(name)
   BOOST_PARAMETER_NAME(index)

   template <class Name, class Index>
   int deduce_arg_types_impl(Name& name, Index& index)
   {
       Name& n2 = name;  // we know the types
       Index& i2 = index;
       return index;
   }

   template <class ArgumentPack>
   int deduce_arg_types(ArgumentPack const& args)
   {
       return deduce_arg_types_impl(args[_name], args[_index|42]);
   }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <cassert>''')

.. @example.append('''
   int a1 = deduce_arg_types((_name = "foo"));
   int a2 = deduce_arg_types((_name = "foo", _index = 3));

   int main()
   {
       assert(a1 == 42);
       assert(a2 == 3);
   }''')

.. @test('run')

Occasionally one needs to deduce argument types without an extra
layer of function call.  For example, suppose we wanted to return
twice the value of the ``index`` parameter?  In that
case we can use the ``value_type< … >`` metafunction introduced
`earlier`__::

   BOOST_PARAMETER_NAME(index)

   template <class ArgumentPack>
   typename parameter::value_type<ArgumentPack, tag::index, int>::type
   twice_index(ArgumentPack const& args)
   {
       return 2 * args[_index|42];
   }

   int six = twice_index(_index = 3);

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/type_traits/remove_reference.hpp>
   #include <cassert>

   namespace parameter = boost::parameter;
   ''')

.. @example.append('''
   int main()
   {
       assert(six == 6);
   }''')

.. @test('run', howmany='all')

Note that if we had used ``binding< … >`` rather than ``value_type< …
>``, we would end up returning a reference to the temporary created in
the ``2 * …`` expression.

__ binding_intro_

Lazy Default Computation
========================

When a default value is expensive to compute, it would be
preferable to avoid it until we're sure it's absolutely necessary.
``BOOST_PARAMETER_FUNCTION`` takes care of that problem for us, but
when using |ArgumentPack|\ s explicitly, we need a tool other than
``operator|``::

   BOOST_PARAMETER_NAME(s1)
   BOOST_PARAMETER_NAME(s2)
   BOOST_PARAMETER_NAME(s3)

   template <class ArgumentPack>
   std::string f(ArgumentPack const& args)
   {
       std::string const& s1 = args[_s1];
       std::string const& s2 = args[_s2];
       typename parameter::binding<
           ArgumentPack,tag::s3,std::string
       >::type s3 = args[_s3|(s1+s2)]; // always constructs s1+s2
       return s3;
   }

   std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <string>
   
   namespace parameter = boost::parameter;''')

.. @example.append('''
   int main()
   {}''')

.. @test('run')

In the example above, the string ``"hello, world"`` is constructed
despite the fact that the user passed us a value for ``s3``.  To
remedy that, we can compute the default value *lazily* (that is,
only on demand), by using ``boost::bind()`` to create a function
object.

.. danielw: I'm leaving the text below in the source, because we might
.. want to change back to it after 1.34, and if I remove it now we
.. might forget about it.

.. by combining the logical-or (“``||``”) operator
.. with a function object built by the Boost Lambda_ library: [#bind]_

.. parsed-literal::

   typename parameter::binding<
       ArgumentPack, tag::s3, std::string
   >::type s3 = args[_s3
       **|| boost::bind(std::plus<std::string>(), boost::ref(s1), boost::ref(s2))** ];

.. @example.prepend('''
   #include <boost/bind.hpp>
   #include <boost/ref.hpp>
   #include <boost/parameter.hpp>
   #include <string>
   #include <functional>

   namespace parameter = boost::parameter;

   BOOST_PARAMETER_NAME(s1)
   BOOST_PARAMETER_NAME(s2)
   BOOST_PARAMETER_NAME(s3)

   template <class ArgumentPack>
   std::string f(ArgumentPack const& args)
   {
       std::string const& s1 = args[_s1];
       std::string const& s2 = args[_s2];''')

.. @example.append('''
       return s3;
   }

   std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));

   int main()
   {}''')

.. @test('run')

.. .. _Lambda: ../../../lambda/index.html

.. sidebar:: Mnemonics

   To remember the difference between ``|`` and ``||``, recall that
   ``||`` normally uses short-circuit evaluation: its second
   argument is only evaluated if its first argument is ``false``.
   Similarly, in ``color_map[param||f]``, ``f`` is only invoked if
   no ``color_map`` argument was supplied.

The expression ``bind(std::plus<std::string>(), ref(s1), ref(s2))`` yields
a *function object* that, when invoked, adds the two strings together.
That function will only be invoked if no ``s3`` argument is supplied by 
the caller.

.. The expression ``lambda::var(s1)+lambda::var(s2)`` yields a
.. *function object* that, when invoked, adds the two strings
.. together.  That function will only be invoked if no ``s3`` argument
.. is supplied by the caller.

================ 
 Best Practices
================

By now you should have a fairly good idea of how to use the
Parameter library.  This section points out a few more-marginal
issues that will help you use the library more effectively.

--------------
Keyword Naming
--------------

``BOOST_PARAMETER_NAME`` prepends a leading underscore to the names
of all our keyword objects in order to avoid the following
usually-silent bug:

.. parsed-literal::

  namespace people
  {
    namespace tag { struct name; struct age;  }

    namespace // unnamed
    {
      boost::parameter::keyword<tag::name>& **name**
      = boost::parameter::keyword<tag::name>::instance;
      boost::parameter::keyword<tag::age>& **age**
      = boost::parameter::keyword<tag::age>::instance;
    }

    BOOST_PARAMETER_FUNCTION(
        (void), g, tag, (optional (name, \*, "bob")(age, \*, 42)))
    {
        std::cout << name << ":" << age;
    }

    void f(int age)
    {
    :vellipsis:`\ 
       .
       .
       .
     ` 
       g(**age** = 3); // whoops!
    }
  }

.. @ignore()

Although in the case above, the user was trying to pass the value
``3`` as the ``age`` parameter to ``g``, what happened instead
was that ``f``\ 's ``age`` argument got reassigned the value 3,
and was then passed as a positional argument to ``g``.  Since
``g``'s first positional parameter is ``name``, the default value
for ``age`` is used, and g prints ``3:42``.  Our leading
underscore naming convention that makes this problem less likely
to occur.

In this particular case, the problem could have been detected if
f's ``age`` parameter had been made ``const``, which is always a
good idea whenever possible.  Finally, we recommend that you use
an enclosing namespace for all your code, but particularly for
names with leading underscores.  If we were to leave out the
``people`` namespace above, names in the global namespace
beginning with leading underscores—which are reserved to your C++
compiler—might become irretrievably ambiguous with those in our
unnamed namespace.

----------
Namespaces
----------

In our examples we've always declared keyword objects in (an
unnamed namespace within) the same namespace as the
Boost.Parameter-enabled functions using those keywords:

.. parsed-literal::

  namespace lib
  {
    **BOOST_PARAMETER_NAME(name)
    BOOST_PARAMETER_NAME(index)**

    BOOST_PARAMETER_FUNCTION(
      (int), f, tag, 
      (optional (name,*,"bob")(index,(int),1))
    )
    {
        std::cout << name << ":" << index << std::endl;
        return index;
    }
  }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')
.. @namespace_setup = str(example)
.. @ignore()

Users of these functions have a few choices:

1. Full qualification:

  .. parsed-literal::

    int x = **lib::**\ f(**lib::**\ _name = "jill", **lib::**\ _index = 1);

  This approach is more verbose than many users would like.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

2. Make keyword objects available through
   *using-declarations*:

  .. parsed-literal::

    **using lib::_name;
    using lib::_index;**

    int x = lib::f(_name = "jill", _index = 1);

  This version is much better at the actual call site, but the
  *using-declarations* themselves can be verbose and hard-to
  manage.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

3. Bring in the entire namespace with a *using-directive*:

  .. parsed-literal::

    **using namespace lib;**
    int x = **f**\ (_name = "jill", _index = 3);

  This option is convenient, but it indiscriminately makes the
  *entire* contents of ``lib`` available without qualification.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

If we add an additional namespace around keyword declarations,
though, we can give users more control:

.. parsed-literal::

  namespace lib
  {
    **namespace keywords
    {**
       BOOST_PARAMETER_NAME(name)
       BOOST_PARAMETER_NAME(index)
    **}**

    BOOST_PARAMETER_FUNCTION(
      (int), f, **keywords::**\ tag, 
      (optional (name,*,"bob")(index,(int),1))
    )
    {
        std::cout << name << ":" << index << std::endl;
        return index;
    }
  }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Now users need only a single *using-directive* to bring in just the
names of all keywords associated with ``lib``:

.. parsed-literal::
  
  **using namespace lib::keywords;**
  int y = lib::f(_name = "bob", _index = 2);

.. @example.append('int main() {}')
.. @test('run', howmany='all')

-------------
Documentation
-------------

The interface idioms enabled by Boost.Parameter are completely new
(to C++), and as such are not served by pre-existing documentation
conventions.  

.. Note:: This space is empty because we haven't settled on any
   best practices yet.  We'd be very pleased to link to your
   documentation if you've got a style that you think is worth
   sharing.

============================
 Portability Considerations
============================

Use the `regression test results`_ for the latest Boost release of
the Parameter library to see how it fares on your favorite
compiler.  Additionally, you may need to be aware of the following
issues and workarounds for particular compilers.

.. _`regression test results`: http://www.boost.org/regression/release/user/parameter.html

-----------------
No SFINAE Support
-----------------

Some older compilers don't support SFINAE.  If your compiler meets
that criterion, then Boost headers will ``#define`` the preprocessor
symbol ``BOOST_NO_SFINAE``, and parameter-enabled functions won't be
removed from the overload set based on their signatures.

---------------------------
No Support for |result_of|_
---------------------------

.. |result_of| replace:: ``result_of``

.. _result_of: ../../../utility/utility.htm#result_of

`Lazy default computation`_ relies on the |result_of| class
template to compute the types of default arguments given the type
of the function object that constructs them.  On compilers that
don't support |result_of|, ``BOOST_NO_RESULT_OF`` will be
``#define``\ d, and the compiler will expect the function object to
contain a nested type name, ``result_type``, that indicates its
return type when invoked without arguments.  To use an ordinary
function as a default generator on those compilers, you'll need to
wrap it in a class that provides ``result_type`` as a ``typedef``
and invokes the function via its ``operator()``.

.. 
  Can't Declare |ParameterSpec| via ``typedef``
  =============================================

  In principle you can declare a |ParameterSpec| as a ``typedef``
  for a specialization of ``parameters<…>``, but Microsoft Visual C++
  6.x has been seen to choke on that usage.  The workaround is to use
  inheritance and declare your |ParameterSpec| as a class:

  .. parsed-literal::

       **struct dfs_parameters
         :** parameter::parameters<
             tag::graph, tag::visitor, tag::root_vertex
           , tag::index_map, tag::color_map
       > **{};**


  Default Arguments Unsupported on Nested Templates
  =================================================

  As of this writing, Borland compilers don't support the use of
  default template arguments on member class templates.  As a result,
  you have to supply ``BOOST_PARAMETER_MAX_ARITY`` arguments to every
  use of ``parameters<…>::match``.  Since the actual defaults used
  are unspecified, the workaround is to use
  |BOOST_PARAMETER_MATCH|_ to declare default arguments for SFINAE.

  .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH``

--------------------------------------------------
Compiler Can't See References In Unnamed Namespace
--------------------------------------------------

If you use Microsoft Visual C++ 6.x, you may find that the compiler
has trouble finding your keyword objects.  This problem has been
observed, but only on this one compiler, and it disappeared as the
test code evolved, so we suggest you use it only as a last resort
rather than as a preventative measure.  The solution is to add
*using-declarations* to force the names to be available in the
enclosing namespace without qualification::

    namespace graphs
    {
      using graphs::graph;
      using graphs::visitor;
      using graphs::root_vertex;
      using graphs::index_map;
      using graphs::color_map;
    }

================
 Python Binding
================

.. _python: python.html

Follow `this link`__ for documentation on how to expose
Boost.Parameter-enabled functions to Python with `Boost.Python`_.

__ python.html

===========
 Reference
===========

.. _reference: reference.html

Follow `this link`__ to the Boost.Parameter reference
documentation.  

__ reference.html

==========
 Glossary
==========

.. _arguments:

:Argument (or “actual argument”): the value actually passed to a
  function or class template

.. _parameter:

:Parameter (or “formal parameter”): the name used to refer to an
  argument within a function or class template.  For example, the
  value of ``f``'s *parameter* ``x`` is given by the *argument*
  ``3``::

    int f(int x) { return x + 1 }
    int y = f(3);

==================
 Acknowledgements
==================

The authors would like to thank all the Boosters who participated
in the review of this library and its documentation, most
especially our review manager, Doug Gregor.

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

.. [#old_interface] As of Boost 1.33.0 the Graph library was still
   using an `older named parameter mechanism`__, but there are
   plans to change it to use Boost.Parameter (this library) in an
   upcoming release, while keeping the old interface available for
   backward-compatibility.  

__ ../../../graph/doc/bgl_named_params.html

.. [#odr] The **One Definition Rule** says that any given entity in
   a C++ program must have the same definition in all translation
   units (object files) that make up a program.

.. [#vertex_descriptor] If you're not familiar with the Boost Graph
   Library, don't worry about the meaning of any
   Graph-library-specific details you encounter.  In this case you
   could replace all mentions of vertex descriptor types with
   ``int`` in the text, and your understanding of the Parameter
   library wouldn't suffer.

.. [#ConceptCpp] This is a major motivation behind `ConceptC++`_.

.. _`ConceptC++`: http://www.generic-programming.org/software/ConceptGCC/

.. .. [#bind] The Lambda library is known not to work on `some
..   less-conformant compilers`__.  When using one of those you could
..   use `Boost.Bind`_ to generate the function object::

..      boost::bind(std::plus<std::string>(),s1,s2)

.. [#is_keyword_expression] Here we're assuming there's a predicate
   metafunction ``is_keyword_expression`` that can be used to
   identify models of Boost.Python's KeywordExpression concept.

.. .. __ http://www.boost.org/regression/release/user/lambda.html
.. _Boost.Bind: ../../../bind/index.html


.. [#using] You can always give the illusion that the function
   lives in an outer namespace by applying a *using-declaration*::

      namespace foo_overloads
      {
        // foo declarations here
        void foo() { ... }
        ...
      }
      using foo_overloads::foo;

    This technique for avoiding unintentional argument-dependent
    lookup is due to Herb Sutter.


.. [#sfinae] This capability depends on your compiler's support for SFINAE. 
   **SFINAE**: **S**\ ubstitution **F**\ ailure **I**\ s
   **N**\ ot **A**\ n **E** rror.  If type substitution during the
   instantiation of a function template results in an invalid type,
   no compilation error is emitted; instead the overload is removed
   from the overload set. By producing an invalid type in the
   function signature depending on the result of some condition,
   we can decide whether or not an overload is considered during overload
   resolution.  The technique is formalized in
   the |enable_if|_ utility.  Most recent compilers support SFINAE;
   on compilers that don't support it, the Boost config library
   will ``#define`` the symbol ``BOOST_NO_SFINAE``.
   See
   http://www.semantics.org/once_weakly/w02_SFINAE.pdf for more
   information on SFINAE.

.. |enable_if| replace:: ``enable_if``
.. _enable_if: ../../../utility/enable_if.html


