parameter/doc/reference.rst
2019-10-09 05:39:39 -04:00

7399 lines
238 KiB
ReStructuredText

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The Boost Parameter Library Reference Documentation
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
: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)
|(logo)|__
.. |(logo)| image:: ../../../../boost.png
:alt: Boost
__ ../../../../index.htm
.. _`BoostPro Computing`: http://www.boostpro.com
//////////////////////////////////////////////////////////////////////////////
.. contents::
:depth: 2
//////////////////////////////////////////////////////////////////////////////
.. role:: class
:class: class
.. role:: concept
:class: concept
.. role:: function
:class: function
.. |ArgumentPack| replace:: :concept:`ArgumentPack`
.. |ForwardSequence| replace:: :concept:`Forward Sequence`
.. |ParameterSpec| replace:: :concept:`ParameterSpec`
.. role:: vellipsis
:class: vellipsis
.. section-numbering::
:depth: 2
Preliminaries
=============
This section covers some basic information you'll need to know in order to
understand this reference.
Namespaces
----------
In this document, all unqualified identifiers should be assumed to be defined
in namespace ``boost::parameter`` unless otherwise specified.
Exceptions
----------
No operation described in this document throws an exception unless otherwise
specified.
Thread Safety
-------------
All components of this library can be used safely from multiple threads
without synchronization. [#thread]_
Typography
----------
Names written in :concept:`sans serif type` represent concepts_.
In code blocks, *italic type* represents unspecified text that satisfies the
requirements given in the detailed description that follows the code block.
In a specification of the tokens generated by a macro, **bold type** is used
to highlight the position of the expanded macro argument in the result.
The special character β represents the value of |BOOST_PARAMETER_MAX_ARITY|_.
//////////////////////////////////////////////////////////////////////////////
Terminology
===========
.. |kw| replace:: keyword
.. _kw:
keyword
The name of a function parameter.
.. _keyword tag type:
.. |keyword tag type| replace:: `keyword tag type`_
keyword tag type
A type used to uniquely identify a function parameter. Typically its name
will be the same as that of the parameter.
.. _positional:
.. |positional| replace:: `positional`_
positional argument
An argument passed with no explicit |kw|. Its parameter is determined
in the usual C++ way: by position with respect to a parameter list.
.. _tag type:
.. |tag type| replace:: `tag type`_
tag type
Shorthand for “\ |keyword tag type|.”
.. _keyword object:
.. |keyword object| replace:: `keyword object`_
keyword object
An instance of |keyword|_\ ``<T>`` for some |tag type| ``T``.
.. _tagged reference:
.. |tagged reference| replace:: `tagged reference`_
tagged reference
An object whose type is associated with a |keyword tag type| (the object's
*keyword*), and that holds a reference (to the object's *value*).
As a shorthand, a “tagged reference to ``x``\ ” means a tagged reference
whose *value* is ``x``.
.. _tagged default:
.. |tagged default| replace:: `tagged default`_
tagged default
A |tagged reference| whose *value* represents the value of a
default argument.
.. _tagged lazy default:
.. |tagged lazy default| replace:: `tagged lazy default`_
tagged lazy default
A |tagged reference| whose *value*, when invoked with no arguments,
computes a default argument value.
.. _intended argument type:
.. |intended argument type| replace:: `intended argument type`_
intended argument type
The *intended argument type* of a single-element |ArgumentPack|_ is the
type of its element's *value*. The intended argument type of any other
type ``X`` is ``X`` itself.
.. Note::
In this reference, we will use concept names (and other names) to describe
both types and objects, depending on context. So for example, “an
|ArgumentPack|_\ ” can refer to a type that models |ArgumentPack|_
*or* an object of such a type.
//////////////////////////////////////////////////////////////////////////////
Concepts
========
This section describes the generic type concepts used by the Parameter
library.
|ArgumentPack|
--------------
An |ArgumentPack| is a collection of |tagged reference|\ s to the actual
arguments passed to a function. Every |ArgumentPack| is also a valid `MPL
Forward Sequence`_ and `MPL Associative Sequence`_ consisting of the |keyword
tag type|\ s in its |tagged reference|\ s. If |BOOST_PARAMETER_CAN_USE_MP11|
is defined, then every |ArgumentPack| is also a valid |Boost_MP11|_ map whose
keys are |keyword tag type|\ s. The |singular_cpp|_, |compose_cpp|_, and
|mpl_cpp|_ test programs demonstrate this functionality.
Requirements
............
In the table below,
* ``A`` is a model of |ArgumentPack|
* ``x`` is an instance of ``A``
* ``u`` is a |keyword object| of type ``K``
* ``v`` is a |tagged default| with |tag type| ``L`` and *value* of type ``D``
* ``w`` is a |tagged lazy default| with |tag type| ``M`` and *value* of type ``E const``
* ``z`` is an |ArgumentPack| containing a single element (as created by |keyword|_\ ``<…>::operator=``)
Any exceptions thrown from the invocation of ``w``\ 's *value*
will be propagated to the caller.
.. table:: |ArgumentPack| requirements
+------------+---------------------------------+----------------+----------------------+
| Expression | Type | Requirements | Semantics/Notes |
+============+=================================+================+======================+
| ``x[u]`` | ``binding<A, K>::type`` | ``x`` contains | Returns *b*\ 's |
| | | an element *b* | *value* (by |
| | | whose |kw|_ is | reference). |
| | | ``K`` | |
+------------+---------------------------------+----------------+----------------------+
| ``x[u]`` | ``binding<A, L, D>::type`` | *none* | If ``x`` contains an |
| | | | element *b* whose |
| | | | |kw|_ is the same as |
| | | | ``u``\ 's, returns |
| | | | *b*\ 's *value* (by |
| | | | reference). |
| | | | Otherwise, returns |
| | | | ``u``\ 's *value*. |
+------------+---------------------------------+----------------+----------------------+
| ``x[w]`` | ``lazy_binding<A, M, E>::type`` | *none* | If ``x`` contains an |
| | | | element *b* whose |
| | | | |kw|_ is the same as |
| | | | ``w``\ 's, returns |
| | | | *b*\ 's *value* (by |
| | | | reference). |
| | | | Otherwise, invokes |
| | | | ``w``\ 's *value* |
| | | | and returns the |
| | | | result. |
+------------+---------------------------------+----------------+----------------------+
| ``x, z`` | Model of |ArgumentPack|_ | *none* | Returns an |
| | | | |ArgumentPack|_ |
| | | | containing all the |
| | | | elements of both |
| | | | ``x`` and ``z``. |
+------------+---------------------------------+----------------+----------------------+
.. _parameterspec:
|ParameterSpec|
---------------
A |ParameterSpec| describes the type requirements for arguments corresponding
to a given |kw|_ and indicates whether the argument is optional or
required. The table below details the allowed forms and describes their
condition for satisfaction by an actual argument type. In each row,
.. _conditions:
* ``K`` is the |ParameterSpec|\ 's |keyword tag type|
* ``A`` is an |intended argument type| associated with ``K``, if any
* ``P`` is a model of |ArgumentPack| that contains ``A``
* ``F`` is an `MPL Binary Metafunction Class`_
.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html
.. table:: |ParameterSpec| allowed forms and conditions of satisfaction
+------------------------+----------+----------------------------------------+
| Type | ``A`` | Condition ``A`` must satisfy |
| | required | |
+========================+==========+========================================+
| ``K`` | no | *n/a* |
+------------------------+----------+----------------------------------------+
| |optional|_\ ``<K,F>`` | no | ``mpl::apply2<F,A,P>::type::value`` is |
| | | ``true``. |
+------------------------+----------+----------------------------------------+
| |required|_\ ``<K,F>`` | yes | ``mpl::apply2<F,A,P>::type::value`` is |
| | | ``true``. |
+------------------------+----------+----------------------------------------+
The information in a |ParameterSpec| is used to `limit`__ the arguments that
will be matched by `forwarding functions`_.
__ overloadcontrol_
.. _overloadcontrol: index.html#controlling-overload-resolution
.. _forwarding functions: index.html#forwarding-functions
//////////////////////////////////////////////////////////////////////////////
Class Templates
===============
.. |keyword| replace:: ``keyword``
.. _keyword:
``keyword``
-----------
The type of every |keyword object| is a specialization of |keyword|.
:Defined in: |keyword_header|_
.. parsed-literal::
template <typename Tag>
struct keyword
{
typedef Tag tag;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_true|_\ // Enable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::in_reference
>
, |mpl_true|_\ // Enable this overload for "in" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, |ArgumentPack|_
>::type
|assignment operator|_\(T const& value) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
typename |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::out_reference
>
, |mpl_true|_\ // The reference category is "out".
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // The reference category is "forward".
, |mpl_false|_\ // The reference category is neither "out" nor "forward".
>
>::type
, |mpl_if|_\<
|boost_is_const|_\<T>
, |mpl_false|_\ // Disable this overload for reference-to-const types.
, |mpl_true|_\ // Enable this overload for referece-to-mutable types.
>
, |mpl_false|_\ // Disable this overload for references neither "out" nor "forward".
>::type
, |ArgumentPack|_
>::type
|assignment operator|_\(T& value) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_false|_\ // Disable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::in_reference
>
, |mpl_true|_\ // Enable this overload for "in" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, |ArgumentPack|_
>::type
|assignment operator|_\(T const&& value) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_false|_\ // Disable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::consume_reference
>
, |mpl_true|_\ // Enable this overload for "consume" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, |ArgumentPack|_
>::type
|assignment operator|_\(T&& value) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_true|_\ // Enable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::in_reference
>
, |mpl_true|_\ // Enable this overload for "in" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, *tagged default*
>::type
|bitwise or operator|_\(T const& x) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
typename |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::out_reference
>
, |mpl_true|_\ // The reference category is "out".
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // The reference category is "forward".
, |mpl_false|_\ // The reference category is neither "out" nor "forward".
>
>::type
, |mpl_if|_\<
|boost_is_const|_\<T>
, |mpl_false|_\ // Disable this overload for reference-to-const types.
, |mpl_true|_\ // Enable this overload for referece-to-mutable types.
>
, |mpl_false|_\ // Disable this overload for references neither "out" nor "forward".
>::type
, *tagged default*
>::type
|bitwise or operator|_\(T& x) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_false|_\ // Disable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::in_reference
>
, |mpl_true|_\ // Enable this overload for "in" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, *tagged default*
>::type
|bitwise or operator|_\(T const&& x) const;
template <typename T>
constexpr typename |boost_enable_if|_\<
typename |mpl_eval_if|_\<
|boost_is_scalar|_\<T>
, |mpl_false|_\ // Disable this overload for scalar types.
, |mpl_eval_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::consume_reference
>
, |mpl_true|_\ // Enable this overload for "consume" references.
, |mpl_if|_\<
|boost_is_same|_\<
typename Tag\:\:qualifier
, boost::parameter::forward_reference
>
, |mpl_true|_\ // Enable this overload for "forward" references.
, |mpl_false|_\ // Disable this overload for all other reference categories.
>
>
>::type
, *tagged default*
>::type constexpr
|bitwise or operator|_\(T&& value) const;
template <typename F>
constexpr *tagged lazy default* |logical or operator|_\(F const&) const;
template <typename F>
constexpr *tagged lazy default* |logical or operator|_\(F&) const;
static keyword<Tag> const& instance;
static keyword<Tag>& get_\();
};
.. |assignment operator| replace:: ``operator=``
.. _assignment operator:
``operator=``
:Synopsis:
.. parsed-literal::
template <typename T>
constexpr |ArgumentPack|_ operator=(T const& value) const;
template <typename T>
constexpr |ArgumentPack|_ operator=(T& value) const;
template <typename T>
constexpr |ArgumentPack|_ operator=(T const&& value) const;
template <typename T>
constexpr |ArgumentPack|_ operator=(T&& value) const;
:Requires: one of the following:
* The nested ``qualifier`` type of ``Tag`` must be ``forward_reference``.
* To use the ``const`` lvalue reference overload, ``T`` must be scalar, or
the nested ``qualifier`` type of ``Tag`` must be ``in_reference``.
* To use the mutable lvalue reference overload, the nested ``qualifier``
type of ``Tag`` must be ``out_reference`` or ``in_out_reference``, and
``T`` must not be ``const``-qualified.
* To use the ``const`` rvalue reference overload for non-scalar ``T``, the
nested ``qualifier`` type of ``Tag`` must be ``in_reference``.
* To use the mutable rvalue reference overload for non-scalar ``T``, the
nested ``qualifier`` type of ``Tag`` must be ``consume_reference`` or
``move_from_reference``.
:Returns: an |ArgumentPack|_ containing a single |tagged reference| to
``value`` with |kw|_ ``Tag``
.. |bitwise or operator| replace:: ``operator|``
.. _bitwise or operator:
``operator|``
:Synopsis:
.. parsed-literal::
template <typename T>
constexpr *tagged default* operator|(T const& x) const;
template <typename T>
constexpr *tagged default* operator|(T& x) const;
template <typename T>
constexpr *tagged default* operator|(T const&& x) const;
template <typename T>
constexpr *tagged default* operator|(T&& x) const;
:Requires: one of the following:
* The nested ``qualifier`` type of ``Tag`` must be ``forward_reference``.
* To use the ``const`` lvalue reference overload, ``T`` must be scalar, or
the nested ``qualifier`` type of ``Tag`` must be ``in_reference``.
* To use the mutable lvalue reference overload, the nested ``qualifier``
type of ``Tag`` must be ``out_reference`` or ``in_out_reference``, and
``T`` must not be ``const``-qualified.
* To use the ``const`` rvalue reference overload for non-scalar ``T``, the
nested ``qualifier`` type of ``Tag`` must be ``in_reference``.
* To use the mutable rvalue reference overload for non-scalar ``T``, the
nested ``qualifier`` type of ``Tag`` must be ``consume_reference`` or
``move_from_reference``.
:Returns: a |tagged default| with *value* ``x`` and |kw|_ ``Tag``.
.. |logical or operator| replace:: ``operator||``
.. _logical or operator:
``operator||``
:Synopsis:
.. parsed-literal::
template <typename F>
constexpr *tagged lazy default* operator||(F const& g) const;
template <typename F>
constexpr *tagged lazy default* operator||(F& g) const;
:Requires: ``g()`` must be valid, with type
|boost_result_of|_\ ``<F()>::type``. [#no_result_of]_
:Returns: a |tagged lazy default| with *value* ``g`` and |kw|_ ``Tag``.
.. _instance:
``instance``
:Synopsis:
.. parsed-literal::
static keyword<Tag> const& instance;
:Returns: a “singleton instance”: the same object will be returned on each
invocation of ``instance``.
:Thread Safety:
``instance`` can be accessed from multiple threads simultaneously.
.. _get:
``get``
:Synopsis:
.. parsed-literal::
static keyword<Tag>& get\();
.. admonition:: Deprecated
This function has been deprecated in favor of ``instance``.
:Returns: a “singleton instance”: the same object will be returned on each
invocation of ``get()``.
:Thread Safety: ``get()`` can be called from multiple threads simultaneously.
.. |template_keyword| replace:: ``template_keyword``
.. _template_keyword:
``template_keyword``
--------------------
This class template encapsulates a named template parameter. Every type
generated by the |BOOST_PARAMETER_TEMPLATE_KEYWORD|_ macro is a specialization
of |template_keyword|.
:Defined in: |template_keyword_header|_
.. parsed-literal::
template <typename Tag, typename T>
struct template_keyword
{
typedef Tag key_type;
typedef T value_type;
typedef *implementation defined* reference;
};
The |ntp_cpp|_ test program demonstrates proper usage of this class template.
.. |parameters| replace:: ``parameters``
.. _parameters:
``parameters``
--------------
Provides an interface for assembling the actual arguments to a `forwarding
function` into an |ArgumentPack|, in which any |positional| arguments will be
tagged according to the corresponding template argument to ``parameters``.
.. _forwarding function: `forwarding functions`_
:Defined in: |parameters_header|_
.. parsed-literal::
template <typename ...PSpec>
struct parameters
{
template <typename ...Args>
struct |match|_
{
typedef … type;
};
template <typename ...Args>
|ArgumentPack|_ |function call operator|_\(Args&&... args) const;
};
:Requires: Each element in the ``PSpec`` parameter pack must be a model of
|ParameterSpec|_.
.. Note::
In this section, ``R`` ## *i* and ``K`` ## *i* are defined as
follows, for any argument type ``A`` ## *i*:
| let ``D0`` the set [d0, …, d ## *j*] of all **deduced**
| *parameter specs* in the ``PSpec`` parameter pack
| ``R`` ## *i* is the |intended argument type| of ``A`` ## *i*
|
| if ``A`` ## *i* is a result type of ``keyword<T>::`` |assignment operator|_
| then
| ``K`` ## *i* is ``T``
| else
| if some ``A`` ## *j* where *j**i* is a result type of
| ``keyword<T>::`` |assignment operator|_
| *or* some ``P`` ## *j* in *j**i* is **deduced**
| then
| if some *parameter spec* ``d`` ## *j* in ``D`` ## *i*
| matches ``A`` ## *i*
| then
| ``K`` ## *i* is the |keyword tag type| of ``d`` ## *j*.
| ``D``:sub:`i+1` is ``D`` ## *i* - [ ``d`` ## *j*]
| else
| ``K`` ## *i* is the |keyword tag type| of ``P`` ## *i*.
.. |match| replace:: ``match``
.. _match:
``match``
A `Metafunction`_ used to remove a `forwarding function`_ from overload
resolution.
:Returns: if all elements in ``Params...`` are *satisfied* (see below), then
``parameters<Params...>``. Otherwise, ``match<Args...>::type`` is not
defined.
Each element ``P`` in ``Params...`` is **satisfied** if either:
* ``P`` is the *unspecified* default
* **or**, ``P`` is a *keyword tag type*
* **or**, ``P`` is |optional|_ ``<X,F>`` and either
- ``X`` is not ``K`` ## *i* for any *i*,
- **or** ``X`` is some ``K`` ## *i* and ``mpl::apply<F,R`` ## *i*\
``>::type::value`` is ``true``
* **or**, ``P`` is |required|_ ``<X,F>``, and
- ``X`` is some ``K`` ## *i*, **and**
- ``mpl::apply<F,R`` ## *i* ``>::type::value`` is ``true``
.. |function call operator| replace:: ``operator()``
.. _function call operator:
``operator()``
:Synopsis:
.. parsed-literal::
template <typename ...Args>
|ArgumentPack|_ operator()(Args&&... args) const;
:Returns: An |ArgumentPack|_ containing, for each ``a`` ## *i*,
- if ``a`` ## *i* is a single-element |ArgumentPack|, its element
- Otherwise, a |tagged reference| with |kw|_ ``K`` ## *i* and *value*
``a`` ## *i*
.. |optional| replace:: ``optional``
.. |required| replace:: ``required``
.. _optional:
.. _required:
``optional``, ``required``
--------------------------
These templates describe the requirements on a function parameter.
``optional`` is defined in: |optional_header|_
``required`` is defined in: |required_header|_
Both headers are included by: |preprocessor_header|_
:Specializations model: |ParameterSpec|_
.. parsed-literal::
template <typename Tag, typename Predicate = *unspecified*>
struct optional;
template <typename Tag, typename Predicate = *unspecified*>
struct required;
The default value of ``Predicate`` is an unspecified `MPL Binary Metafunction
Class`_ that returns ``mpl::true_`` for any argument. If
|BOOST_PARAMETER_CAN_USE_MP11|_ is defined, then the default value of
``Predicate`` is also a |Boost_MP11|_-style quoted metafunction that returns
``mp11::mp_true`` for any argument.
.. |deduced| replace:: ``deduced``
.. _deduced:
``deduced``
-----------
This template is used to wrap the *keyword tag* argument to
``optional`` or ``required``.
:Defined in: |deduced_header|_
:Included by: |preprocessor_header|_
.. parsed-literal::
template <typename Tag>
struct deduced;
:Requires: nothing
//////////////////////////////////////////////////////////////////////////////
Metafunctions
=============
A `Metafunction`_ is conceptually a function that operates on, and returns,
C++ types.
.. |binding| replace:: ``binding``
.. _binding:
``binding``
-----------
Returns the result type of indexing an argument pack with a
|keyword tag type| or with a |tagged default|.
:Defined in: |binding_header|_
.. parsed-literal::
template <typename A, typename K, typename D = void\_>
struct binding
{
typedef … type;
};
:Requires: ``A`` must be a model of |ArgumentPack|_.
:Returns: the reference type of the |tagged reference| in ``A`` having
|keyword tag type| ``K``, if any. If no such |tagged reference| exists,
returns ``D``.
.. |lazy_binding| replace:: ``lazy_binding``
.. _lazy_binding:
``lazy_binding``
----------------
Returns the result type of indexing an argument pack with a
|tagged lazy default|.
:Defined in: |binding_header|_
.. parsed-literal::
template <typename A, typename K, typename F>
struct lazy_binding
{
typedef … type;
};
:Requires: ``A`` must be a model of |ArgumentPack|_.
:Returns: the reference type of the |tagged reference| in ``A`` having
|keyword tag type| ``K``, if any. If no such |tagged reference| exists,
returns |boost_result_of|_\ ``<F()>::type``. [#no_result_of]_
.. |value_type| replace:: ``value_type``
.. _value_type:
``value_type``
--------------
Returns the result type of indexing an argument pack with a
|keyword tag type| or with a |tagged default|.
:Defined in: |value_type_header|_
.. parsed-literal::
template <typename A, typename K, typename D = void\_>
struct value_type
{
typedef … type;
};
:Requires: ``A`` must be a model of |ArgumentPack|_.
:Returns: the (possibly const-qualified) type of the |tagged reference| in
``A`` having |keyword tag type| ``K``, if any. If no such
|tagged reference| exists, returns ``D``. Equivalent to:
.. parsed-literal::
typename |boost_remove_reference|_\<
typename |binding|_\<A, K, D>::type
>::type
… when ``D`` is not a reference type.
.. |lazy_value_type| replace:: ``lazy_value_type``
.. _lazy_value_type:
``lazy_value_type``
-------------------
Returns the result type of indexing an argument pack with a
|tagged lazy default|.
:Defined in: |value_type_header|_
.. parsed-literal::
template <typename A, typename K, typename F>
struct lazy_value_type
{
typedef … type;
};
:Requires: ``A`` must be a model of |ArgumentPack|_.
:Returns: the (possibly const-qualified) type of the |tagged reference| in
``A`` having |keyword tag type| ``K``, if any. If no such
|tagged reference| exists, returns
|boost_result_of|_\ ``<F()>::type``. [#no_result_of]_
.. |are_tagged_arguments| replace:: ``are_tagged_arguments``
.. _are_tagged_arguments:
``are_tagged_arguments``
------------------------
:Defined in: |are_tagged_arguments_header|_
.. parsed-literal::
template <typename T0, typename ...Pack>
struct are_tagged_arguments
// : |mpl_true|_\ if T0 and all elements in Pack are
// tagged reference types, |mpl_false|_\ otherwise.
{
};
:Returns:
``mpl::true_`` if ``T0`` and all elements in parameter pack ``Pack`` are
|tagged reference| types, ``mpl::false_`` otherwise.
:Example usage:
When implementing a Boost.Parameter-enabled constructor for a container that
conforms to the C++ standard, one needs to remember that the standard requires
the presence of other constructors that are typically defined as templates,
such as range constructors. To avoid overload ambiguities between the two
constructors, use this metafunction in conjunction with ``disable_if`` to
define the range constructor.
.. parsed-literal::
template <typename B>
class frontend : public B
{
struct _enabler
{
};
public:
|BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|_\(frontend, (B))
template <typename Iterator>
frontend(
Iterator itr
, Iterator itr_end
, typename |boost_disable_if|_\<
are_tagged_arguments<Iterator>
, _enabler
>::type = _enabler()
) : B(itr, itr_end)
{
}
};
.. |is_argument_pack| replace:: ``is_argument_pack``
.. _is_argument_pack:
``is_argument_pack``
--------------------
:Defined in: |is_argument_pack_header|_
.. parsed-literal::
template <typename T>
struct is_argument_pack
// : |mpl_true|_\ if T is a model of |ArgumentPack|_\,
// |mpl_false|_\ otherwise.
{
};
:Returns:
``mpl::true_`` if ``T`` is a model of |ArgumentPack|_, ``mpl::false_``
otherwise.
:Example usage:
To avoid overload ambiguities between a constructor that takes in an
|ArgumentPack|_ and a templated conversion constructor, use this
metafunction in conjunction with ``enable_if``.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(a0)
template <typename T>
class backend0
{
struct _enabler
{
};
T a0;
public:
template <typename ArgPack>
explicit backend0(
ArgPack const& args
, typename |boost_enable_if|_\<
is_argument_pack<ArgPack>
, _enabler
>::type = _enabler()
) : a0(args[_a0])
{
}
template <typename U>
backend0(
backend0<U> const& copy
, typename |boost_enable_if|_\<
|boost_is_convertible|_\<U,T>
, _enabler
>::type = _enabler()
) : a0(copy.get_a0())
{
}
T const& get_a0() const
{
return this->a0;
}
};
.. |result_of_compose| replace:: ``result_of::compose``
.. _result_of_compose:
``result_of::compose``
----------------------
Returns the result type of the |compose|_ function.
:Defined in: |compose_header|_
.. parsed-literal::
template <typename ...TaggedArgs>
struct compose
: |boost_enable_if|_\<
|are_tagged_arguments|_\<T0,Pack...>
, |ArgumentPack|_
>
{
};
template <>
struct compose<>
{
typedef *empty* |ArgumentPack|_ type;
};
:Requires: All elements in ``TaggedArgs`` must be |tagged reference| types, if
specified.
:Returns: the result type of the |compose|_ function.
//////////////////////////////////////////////////////////////////////////////
Function Templates
==================
.. |compose| replace:: ``compose``
.. _compose:
``compose``
-----------
:Defined in: |compose_header|_
.. parsed-literal::
template <typename ...Pack>
constexpr typename |result_of_compose|_\<Pack...>::type
compose(Pack const&... args);
This function facilitates easier variadic argument composition. It is used by
the |BOOST_PARAMETER_NO_SPEC_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR|_,
|BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR|_,
|BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|_, and
|BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR|_ code generation macros. You
can use it to write your own code generation macros if the ones provided by
this library do not suffice.
Unlike the |tagged reference| comma operator, the ``compose()`` function is
variadic, as mentioned before. However, the |tagged reference| comma operator
can be invoked indefinitely and therefore does not limit the size of the
resulting |ArgumentPack|, while the ``compose()`` function cannot take in more
than |BOOST_PARAMETER_COMPOSE_MAX_ARITY|_ arguments for compilers that do not
support perfect forwarding.
:Requires: All elements in ``args`` must be |tagged reference| objects, if
specified.
:Returns: an |ArgumentPack|_ containing all elements in ``args``, if
specified; an empty |ArgumentPack|_ otherwise.
:Example usage:
.. parsed-literal::
BOOST_PARAMETER_NAME(index)
BOOST_PARAMETER_NAME(name)
template <typename ArgumentPack>
int print_name_and_index(ArgumentPack const& args)
{
std::cout << "index = " << args[_index];
std::cout << "name = " << args[_name];
std::cout << "; " << std::endl;
return 0;
}
int y = print_name_and_index(compose(_index = 3, _name = "jones"));
The |compose_cpp|_ test program shows more examples using this function.
//////////////////////////////////////////////////////////////////////////////
Code Generation Macros
======================
Macros in this section can be used to ease the writing of code
using the Parameter library by eliminating repetitive boilerplate.
.. |BOOST_PARAMETER_FUNCTION| replace:: ``BOOST_PARAMETER_FUNCTION``
.. _BOOST_PARAMETER_FUNCTION:
``BOOST_PARAMETER_FUNCTION(result, name, tag_namespace, arguments)``
--------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal function header. Enclose the
return type ``bool`` in parentheses. For each parameter, also enclose the
expected value type in parentheses. Since the value types are mutually
exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. Also, just as with a normal
function, optional parameters have default values, whereas required parameters
do not. Within the function body, either simply use the parameter name or
pass the matching identifier with the leading underscore to the bracket
operator of ``args`` to extract the corresponding argument. Note that the
second method doesn't require ``std::forward`` to preserve value categories.
.. parsed-literal::
BOOST_PARAMETER_FUNCTION((bool), evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>), rvalue_const_bitset<2>())
(rr, (|std_bitset|_\<4>), rvalue_bitset<3>())
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(lrc)
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(lr)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(|std_forward|_\<rrc0_type>(rrc0))
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr0])
);
return true;
}
The following function calls are legal.
.. parsed-literal::
evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_, |preprocessor_deduced_cpp|_, and
|preprocessor_eval_cat_cpp|_ test programs demonstrate proper usage of this
macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*optional-specifier* {*optional-specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*required-specifier* {*required-specifier*\ }
'**)**'
)
optional-specifier ::=
'**(**'
*argument-name* '**,**' *restriction* '**,**' *default-value*
')'
required-specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``default-value`` is any valid C++ expression; if necessary, user code can
compute it in terms of ``previous-name ## _type``, where ``previous-name``
is the ``argument-name`` in a previous ``specifier-group0`` or
``specifier-group1``. *This expression will be invoked exactly once.*
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**. If
``restriction`` uses this form, then the type of the generated name
``argument-name ## _type`` will be computed in terms of the **target
type**, and the generated reference ``argument-name`` (but not its
corresponding entry in ``args``) will be cast to that type.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## __LINE__ ## **name**\ (Args const&);
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **m**
);
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
);
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## __LINE__ ## **name**\ (Args const& args)
{
return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
static_cast<
typename boost_param_result\_ ## __LINE__ ## **name**\ <
Args
>::type(*)()
>(|std_nullptr|_\)
, args
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **0**
>::type
>(args[ *keyword object of required parameter* ## **0**])
, …
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **n**
>::type
>(args[ *keyword object of required parameter* ## **n**])
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **n**
)
{
return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
static_cast<ResultType(*)()>(|std_nullptr|_\)
, (args, *keyword object of optional parameter* ## **n + 1** =
*default value of optional parameter* ## **n + 1**
)
, |std_forward|_\<*argument name* ## **0** ## _type>(
*argument name* ## **0**
)
, …
, |std_forward|_\<*argument name* ## **n** ## _type>(
*argument name* ## **n**
)
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of optional parameter* ## **n + 1**
>::type
>(*default value of optional parameter* ## **n + 1**)
);
}
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
)
.. |BOOST_PARAMETER_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_MEMBER_FUNCTION:
``BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, arguments)``
---------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a member function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``static`` member function
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. Also, just as with a normal
function, optional parameters have default values, whereas required parameters
do not. Within the function body, either simply use the parameter name or
pass the matching identifier with the leading underscore to the bracket
operator of ``args`` to extract the corresponding argument. Note that the
second method doesn't require ``std::forward`` to preserve value categories.
.. parsed-literal::
struct B
{
BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>), rvalue_const_bitset<2>())
(rr, (|std_bitset|_\<4>), rvalue_bitset<3>())
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(lrc)
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(lr)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(|std_forward|_\<rrc0_type>(rrc0))
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr0])
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B::evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
B::evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
B::evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
B::evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
B::evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
B::evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
B::evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ and |preprocessor_eval_cat_cpp|_ test programs
demonstrate proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions. ``name`` may be qualified by the
``static`` keyword to declare the member function and its helpers as not
associated with any object of the enclosing type.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*optional-specifier* {*optional-specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*required-specifier* {*required-specifier*\ }
'**)**'
)
optional-specifier ::=
'**(**'
*argument-name* '**,**' *restriction* '**,**' *default-value*
')'
required-specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``default-value`` is any valid C++ expression; if necessary, user code can
compute it in terms of ``previous-name ## _type``, where ``previous-name``
is the ``argument-name`` in a previous ``specifier-group0`` or
``specifier-group1``. *This expression will be invoked exactly once.*
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**. If
``restriction`` uses this form, then the type of the generated name
``argument-name ## _type`` will be computed in terms of the **target
type**, and the generated reference ``argument-name`` (but not its
corresponding entry in ``args``) will be cast to that type.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return this->boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return this->boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## __LINE__ ## **name**\ (Args const& args)
{
return this->boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
static_cast<
typename boost_param_result\_ ## __LINE__ ## **name**\ <
Args
>::type(*)()
>(|std_nullptr|_\)
, args
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **0**
>::type
>(args[ *keyword object of required parameter* ## **0**])
, …
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **n**
>::type
>(args[ *keyword object of required parameter* ## **n**])
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **n**
)
{
return this->boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
static_cast<ResultType(*)()>(|std_nullptr|_\)
, (args, *keyword object of optional parameter* ## **n + 1** =
*default value of optional parameter* ## **n + 1**
)
, |std_forward|_\<*argument name* ## **0** ## _type>(
*argument name* ## **0**
)
, …
, |std_forward|_\<*argument name* ## **n** ## _type>(
*argument name* ## **n**
)
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of optional parameter* ## **n + 1**
>::type
>(*default value of optional parameter* ## **n + 1**)
);
}
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
)
.. |BOOST_PARAMETER_CONST_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_CONST_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_CONST_MEMBER_FUNCTION:
``BOOST_PARAMETER_CONST_MEMBER_FUNCTION(result, name, tag_ns, arguments)``
--------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a member function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``const`` member function
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. Also, just as with a normal
function, optional parameters have default values, whereas required parameters
do not. Within the function body, either simply use the parameter name or
pass the matching identifier with the leading underscore to the bracket
operator of ``args`` to extract the corresponding argument. Note that the
second method doesn't require ``std::forward`` to preserve value categories.
.. parsed-literal::
struct B
{
B()
{
}
BOOST_PARAMETER_CONST_MEMBER_FUNCTION((bool), evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>), rvalue_const_bitset<2>())
(rr, (|std_bitset|_\<4>), rvalue_bitset<3>())
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(lrc)
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(lr)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(|std_forward|_\<rrc0_type>(rrc0))
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr0])
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B const b = B();
b.evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
b.evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
b.evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
b.evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
b.evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
b.evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
b.evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*optional-specifier* {*optional-specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*required-specifier* {*required-specifier*\ }
'**)**'
)
optional-specifier ::=
'**(**'
*argument-name* '**,**' *restriction* '**,**' *default-value*
')'
required-specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``default-value`` is any valid C++ expression; if necessary, user code can
compute it in terms of ``previous-name ## _type``, where ``previous-name``
is the ``argument-name`` in a previous ``specifier-group0`` or
``specifier-group1``. *This expression will be invoked exactly once.*
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**. If
``restriction`` uses this form, then the type of the generated name
``argument-name ## _type`` will be computed in terms of the **target
type**, and the generated reference ``argument-name`` (but not its
corresponding entry in ``args``) will be cast to that type.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result_const\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result_const\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params_const\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params_const\_ ## __LINE__ ## **name**
boost_param_parameters_const\_ ## __LINE__ ## **name**;
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters_const\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()
) const
{
return this->boost_param_impl_const ## __LINE__ ## **name**\ (
boost_param_parameters_const\_ ## __LINE__ ## **name**\ (
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters_const\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()
) const
{
return this->boost_param_impl_const ## __LINE__ ## **name**\ (
boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result_const\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl_const ## __LINE__ ## **name**\ (Args const& args) const
{
return this->
boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ (
static_cast<
typename boost_param_result_const\_ ## __LINE__ ## **name**\ <
Args
>::type(*)()
>(|std_nullptr|_\)
, args
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **0**
>::type
>(args[ *keyword object of required parameter* ## **0**])
, …
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **n**
>::type
>(args[ *keyword object of required parameter* ## **n**])
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **n**
) const
{
return this->
boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ (
static_cast<ResultType(*)()>(|std_nullptr|_\)
, (args, *keyword object of optional parameter* ## **n + 1** =
*default value of optional parameter* ## **n + 1**
)
, |std_forward|_\<*argument name* ## **0** ## _type>(
*argument name* ## **0**
)
, …
, |std_forward|_\<*argument name* ## **n** ## _type>(
*argument name* ## **n**
)
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of optional parameter* ## **n + 1**
>::type
>(*default value of optional parameter* ## **n + 1**)
);
}
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
) const
.. |BOOST_PARAMETER_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_FUNCTION_CALL_OPERATOR(result, tag_namespace, arguments)``
----------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function call operator that can take in positional arguments,
composed arguments, named arguments, and deduced arguments.
:Example usage:
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``tag`` by default.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(y)
|BOOST_PARAMETER_NAME|_\(z)
Use the macro as a substitute for a normal function call operator
header. Enclose the return type in parentheses. For each parameter, also
enclose the expected value type in parentheses. Since the value types are
mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. This is especially useful when implementing multiple
Boost.Parameter-enabled function call operator overloads.
.. parsed-literal::
class char_reader
{
int index;
char const* key;
public:
explicit char_reader(char const* k) : index(0), key(k)
{
}
BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), tag,
(deduced
(required
(y, (int))
(z, (char const*))
)
)
)
{
this->index = y;
this->key = z;
}
|BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR|_\((char), tag,
(deduced
(required
(y, (bool))
(z, (|std_map|_\<char const*, |std_string|_\>))
)
)
)
{
return y ? (
(z.find(this->key)->second)[this->index]
) : this->key[this->index];
}
};
As with regular argument-dependent lookup, the value types of the arguments
passed in determine which function call operator overload gets invoked.
.. parsed-literal::
char const* keys[] = {"foo", "bar", "baz"};
|std_map|_\<char const*, |std_string|_\> k2s;
k2s[keys[0]] = |std_string|_\("qux");
k2s[keys[1]] = |std_string|_\("wmb");
k2s[keys[2]] = |std_string|_\("zxc");
char_reader r(keys[0]);
// positional arguments
BOOST_TEST_EQ('q', (r(true, k2s)));
BOOST_TEST_EQ('f', (r(false, k2s)));
// named arguments
r(_z = keys[1], _y = 1);
BOOST_TEST_EQ('m', (r(_z = k2s, _y = true)));
BOOST_TEST_EQ('a', (r(_z = k2s, _y = false)));
// deduced arguments
r(keys[2], 2);
BOOST_TEST_EQ('c', (r(k2s, true)));
BOOST_TEST_EQ('z', (r(k2s, false)));
The |preprocessor_cpp|_ and |preprocessor_deduced_cpp|_ test programs
demonstrate proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
* ``tag_namespace`` is the namespace in which the keywords used by the
function call operator resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*optional-specifier* {*optional-specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*required-specifier* {*required-specifier*\ }
'**)**'
)
optional-specifier ::=
'**(**'
*argument-name* '**,**' *restriction* '**,**' *default-value*
')'
required-specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``default-value`` is any valid C++ expression; if necessary, user code can
compute it in terms of ``previous-name ## _type``, where ``previous-name``
is the ``argument-name`` in a previous ``specifier-group0`` or
``specifier-group1``. *This expression will be invoked exactly once.*
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**. If
``restriction`` uses this form, then the type of the generated name
``argument-name ## _type`` will be computed in terms of the **target
type**, and the generated reference ``argument-name`` (but not its
corresponding entry in ``args``) will be cast to that type.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## operator
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## operator
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## operator
boost_param_parameters\_ ## __LINE__ ## operator;
template <typename A0, …, typename A ## **n**>
**result** operator()(
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## operator::match<
A0, …, A ## **n**
>::type = boost_param_parameters\_ ## __LINE__ ## operator()
)
{
return this->boost_param_impl ## __LINE__ ## operator(
boost_param_parameters\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** operator()(
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## operator::match<
A0, …, A ## **m**
>::type = boost_param_parameters\_ ## __LINE__ ## operator()
)
{
return this->boost_param_impl ## __LINE__ ## operator(
boost_param_parameters\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## operator<Args>::type
boost_param_impl ## __LINE__ ## operator(Args const& args)
{
return this->boost_param_dispatch_0boost\_ ## __LINE__ ## operator(
static_cast<
typename boost_param_result\_ ## __LINE__ ## operator<
Args
>::type(*)()
>(|std_nullptr|_\)
, args
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **0**
>::type
>(args[ *keyword object of required parameter* ## **0**])
, …
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **n**
>::type
>(args[ *keyword object of required parameter* ## **n**])
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **n**
)
{
return this->boost_param_dispatch_0boost\_ ## __LINE__ ## operator(
static_cast<ResultType(*)()>(|std_nullptr|_\)
, (args, *keyword object of optional parameter* ## **n + 1** =
*default value of optional parameter* ## **n + 1**
)
, |std_forward|_\<*argument name* ## **0** ## _type>(
*argument name* ## **0**
)
, …
, |std_forward|_\<*argument name* ## **n** ## _type>(
*argument name* ## **n**
)
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of optional parameter* ## **n + 1**
>::type
>(*default value of optional parameter* ## **n + 1**)
);
}
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_0boost\_ ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
)
.. |BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR(result, tag_ns, arguments)``
---------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function call operator that can take in positional arguments,
composed arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``const`` function call operator
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. Also, just as with a normal
function, optional parameters have default values, whereas required parameters
do not. Within the function body, either simply use the parameter name or
pass the matching identifier with the leading underscore to the bracket
operator of ``args`` to extract the corresponding argument. Note that the
second method doesn't require ``std::forward`` to preserve value categories.
.. parsed-literal::
struct B
{
B()
{
}
BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((bool), kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>), rvalue_const_bitset<2>())
(rr, (|std_bitset|_\<4>), rvalue_bitset<3>())
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(lrc)
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(lr)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(|std_forward|_\<rrc0_type>(rrc0))
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr0])
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B const b = B();
b( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
b( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
b(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
b( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
b( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
b( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
b( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_, |preprocessor_deduced_cpp|_, and
|preprocessor_eval_cat_8_cpp|_ test programs demonstrate proper usage of this
macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
* ``tag_namespace`` is the namespace in which the keywords used by the
function call operator resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*optional-specifier* {*optional-specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*required-specifier* {*required-specifier*\ }
'**)**'
)
optional-specifier ::=
'**(**'
*argument-name* '**,**' *restriction* '**,**' *default-value*
')'
required-specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``default-value`` is any valid C++ expression; if necessary, user code can
compute it in terms of ``previous-name ## _type``, where ``previous-name``
is the ``argument-name`` in a previous ``specifier-group0`` or
``specifier-group1``. *This expression will be invoked exactly once.*
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**. If
``restriction`` uses this form, then the type of the generated name
``argument-name ## _type`` will be computed in terms of the **target
type**, and the generated reference ``argument-name`` (but not its
corresponding entry in ``args``) will be cast to that type.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result_const\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result_const\_ ## __LINE__ ## operator
{
typedef **result** type;
};
struct boost_param_params_const\_ ## __LINE__ ## operator
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params_const\_ ## __LINE__ ## operator
boost_param_parameters_const\_ ## __LINE__ ## operator;
template <typename A0, …, typename A ## **n**>
**result** operator()(
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters_const\_ ## __LINE__ ## operator
::match<A0, …, A ## **n**>::type
= boost_param_parameters_const\_ ## __LINE__ ## operator()
) const
{
return this->boost_param_impl_const ## __LINE__ ## operator(
boost_param_parameters_const\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** operator()(
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters_const\_ ## __LINE__ ## operator
::match<A0, …, A ## **m**>::type
= boost_param_parameters_const\_ ## __LINE__ ## operator()
) const
{
return this->boost_param_impl_const ## __LINE__ ## operator(
boost_param_parameters_const\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result_const\_ ## __LINE__ ## operator<Args>::type
boost_param_impl_const ## __LINE__ ## operator(Args const& args) const
{
return this->
boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator(
static_cast<
typename boost_param_result_const\_ ## __LINE__ ## operator<
Args
>::type(*)()
>(|std_nullptr|_\)
, args
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **0**
>::type
>(args[ *keyword object of required parameter* ## **0**])
, …
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of required parameter* ## **n**
>::type
>(args[ *keyword object of required parameter* ## **n**])
);
}
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **n** ## _type
>
ResultType
boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **n** ## _type&& *argument name* ## **n**
) const
{
return this->
boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator(
static_cast<ResultType(*)()>(|std_nullptr|_\)
, (args, *keyword object of optional parameter* ## **n + 1** =
*default value of optional parameter* ## **n + 1**
)
, |std_forward|_\<*argument name* ## **0** ## _type>(
*argument name* ## **0**
)
, …
, |std_forward|_\<*argument name* ## **n** ## _type>(
*argument name* ## **n**
)
, |std_forward|_\<
typename |value_type|_\<
Args
, *keyword tag type of optional parameter* ## **n + 1**
>::type
>(*default value of optional parameter* ## **n + 1**)
);
}
:vellipsis:`⋮`
template <
typename ResultType
, typename Args
, typename *argument name* ## **0** ## _type
, …
, typename *argument name* ## **m** ## _type
>
ResultType
boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
, *argument name* ## **0** ## _type&& *argument name* ## **0**
, …
, *argument name* ## **m** ## _type&& *argument name* ## **m**
) const
.. |BOOST_PARAMETER_CONSTRUCTOR| replace:: ``BOOST_PARAMETER_CONSTRUCTOR``
.. _BOOST_PARAMETER_CONSTRUCTOR:
``BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, arguments)``
--------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a constructor that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``tag`` by default.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(y)
|BOOST_PARAMETER_NAME|_\(z)
In the base class, implement a delegate constructor template that takes in an
|ArgumentPack|_. You must pass the identifiers with leading underscores to
``args`` in order to extract the corresponding arguments.
.. parsed-literal::
class char_read_base
{
int index;
char const* key;
public:
template <typename Args>
explicit char_read_base(Args const& args)
: index(args[_y]), key(args[_z])
{
}
|BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR|_\((char), tag,
(deduced
(required
(y, (bool))
(z, (|std_map|_\<char const*, |std_string|_\>))
)
)
)
{
return y ? (
(z.find(this->key)->second)[this->index]
) : this->key[this->index];
}
};
Use the macro as a substitute for a normal constructor definition. Note the
lack of an explicit body. Enclose the base type in parentheses. For each
parameter, also enclose the expected value type in parentheses. Since the
value types are mutually exclusive, you can wrap the parameters in a
``(deduced …)`` clause.
.. parsed-literal::
struct char_reader : public char_read_base
{
BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), tag,
(deduced
(required
(y, (int))
(z, (char const*))
)
)
)
};
The following ``char_reader`` constructor calls are legal.
.. parsed-literal::
char const* keys[] = {"foo", "bar", "baz"};
|std_map|_\<char const*, |std_string|_\> k2s;
k2s[keys[0]] = |std_string|_\("qux");
k2s[keys[1]] = |std_string|_\("wmb");
k2s[keys[2]] = |std_string|_\("zxc");
// positional arguments
char_reader r0(0, keys[0]);
BOOST_TEST_EQ('q', (r0(true, k2s)));
BOOST_TEST_EQ('f', (r0(false, k2s)));
// named arguments
char_reader r1(_z = keys[1], _y = 1);
BOOST_TEST_EQ('m', (r1(_z = k2s, _y = true)));
BOOST_TEST_EQ('a', (r1(_z = k2s, _y = false)));
// deduced arguments
char_reader r2(keys[2], 2);
BOOST_TEST_EQ('c', (r2(k2s, true)));
BOOST_TEST_EQ('z', (r2(k2s, false)));
The |preprocessor_cpp|_ and |preprocessor_deduced_cpp|_ test programs
demonstrate proper usage of this macro.
**Macro parameters:**
* ``cls`` is the name of the enclosing class.
* ``impl`` is the parenthesized implementation base class for ``cls``.
* ``tag_namespace`` is the namespace in which the keywords used by the
constructor resides.
* ``arguments`` is a list of *argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
delegate constructor in ``impl`` to determine the default value of all
optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
struct boost_param_params\_ ## __LINE__ ## ctor
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## ctor
constructor_parameters ## __LINE__;
template <typename A0, …, typename A ## **n**>
**cls**\ (A0&& a0, …, A ## **n** && a ## **n**)
: **impl**\ (
constructor_parameters ## __LINE__(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
)
{
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**cls**\ (A0&& a0, …, A ## **m** && a ## **m**)
: **impl**\ (
constructor_parameters ## __LINE__(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
)
{
}
.. |BOOST_PARAMETER_BASIC_FUNCTION| replace:: ``BOOST_PARAMETER_BASIC_FUNCTION``
.. _BOOST_PARAMETER_BASIC_FUNCTION:
``BOOST_PARAMETER_BASIC_FUNCTION(result, name, tag_namespace, arguments)``
--------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal function header. Enclose the
return type ``bool`` in parentheses. For each parameter, also enclose the
expected value type in parentheses. Since the value types are mutually
exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. However, unlike a normal
function, default values must be specified within the function body. Also
within the function body, you must pass the matching identifier with the
leading underscore to the bracket operator of ``args`` to extract the
corresponding argument, but at least this doesn't require ``std::forward`` to
preserve value categories.
.. parsed-literal::
BOOST_PARAMETER_BASIC_FUNCTION((bool), evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>))
(rr, (|std_bitset|_\<4>))
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc0 | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr0 | rvalue_bitset<3>()])
);
return true;
}
The following function calls are legal.
.. parsed-literal::
evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
function body to determine the default value of all optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## **name**\ (Args const&);
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return boost_param_impl ## __LINE__ ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## __LINE__ ## **name**\ (Args const& args)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_BASIC_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_BASIC_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_BASIC_MEMBER_FUNCTION:
``BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_ns, arguments)``
--------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a member function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``static`` member function
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. However, unlike a normal
function, default values must be specified within the function body. Also
within the function body, you must pass the matching identifier with the
leading underscore to the bracket operator of ``args`` to extract the
corresponding argument, but at least this doesn't require ``std::forward`` to
preserve value categories.
.. parsed-literal::
struct B
{
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((bool), static evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>))
(rr, (|std_bitset|_\<4>))
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc0 | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr0 | rvalue_bitset<3>()]
)
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B::evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
B::evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
B::evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
B::evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
B::evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
B::evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
B::evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions. ``name`` may be qualified by the
``static`` keyword to declare the member function and its helpers as not
associated with any object of the enclosing type.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
function body to determine the default value of all optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return this->boost_param_impl ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
return this->boost_param_impl ## **name**\ (
boost_param_parameters\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl ## **name**\ (Args const& args)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION:
``BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(result, name, tag_ns, args)``
---------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a member function that can take in positional arguments, composed
arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``const`` member function
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. However, unlike a normal
function, default values must be specified within the function body. Also
within the function body, you must pass the matching identifier with the
leading underscore to the bracket operator of ``args`` to extract the
corresponding argument, but at least this doesn't require ``std::forward`` to
preserve value categories.
.. parsed-literal::
struct B
{
B()
{
}
BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((bool), evaluate, kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>))
(rr, (|std_bitset|_\<4>))
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc0 | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr0 | rvalue_bitset<3>()]
)
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B const b = B();
b.evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
b.evaluate( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
b.evaluate(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
b.evaluate( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
b.evaluate( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
b.evaluate( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
b.evaluate( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated forwarding functions.
* ``tag_namespace`` is the namespace in which the keywords used by the
function resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
function body to determine the default value of all optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result_const\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result_const\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params_const\_ ## __LINE__ ## **name**
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params_const\_ ## __LINE__ ## **name**
boost_param_parameters_const\_ ## __LINE__ ## **name**;
template <typename A0, …, typename A ## **n**>
**result** **name**\ (
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters_const\_ ## __LINE__ ## **name**
::match<A0, …, A ## **n**>::type
= boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()
) const
{
return this->boost_param_impl_const ## __LINE__ ## **name**\ (
boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** **name**\ (
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters_const\_ ## __LINE__ ## **name**
::match<A0, …, A ## **m**>::type
= boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()
) const
{
return this->boost_param_impl_const ## __LINE__ ## **name**\ (
boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result_const\_ ## __LINE__ ## **name**\ <Args>::type
boost_param_impl_const ## __LINE__ ## **name**\ (Args const& args) const
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR(result, tag_ns, arguments)``
---------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function call operator that can take in positional arguments,
composed arguments, named arguments, and deduced arguments.
:Example usage:
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``tag`` by default.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(y)
|BOOST_PARAMETER_NAME|_\(z)
Use the macro as a substitute for a normal function call operator
header. Enclose the return type in parentheses. For each parameter, also
enclose the expected value type in parentheses. Since the value types are
mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. This is especially useful when implementing multiple
Boost.Parameter-enabled function call operator overloads.
.. parsed-literal::
class char_reader
{
int index;
char const* key;
public:
explicit char_reader(char const* k) : index(0), key(k)
{
}
BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((void), tag,
(deduced
(required
(y, (int))
(z, (char const*))
)
)
)
{
this->index = args[_y];
this->key = args[_z];
}
|BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR|_\((char), tag,
(deduced
(required
(y, (bool))
(z, (|std_map|_\<char const*, |std_string|_\>))
)
)
)
{
return args[_y] ? (
(args[_z].find(this->key)->second)[this->index]
) : this->key[this->index];
}
};
As with regular argument-dependent lookup, the value types of the arguments
passed in determine which function call operator overload gets invoked.
.. parsed-literal::
char const* keys[] = {"foo", "bar", "baz"};
|std_map|_\<char const*, |std_string|_\> k2s;
k2s[keys[0]] = |std_string|_\("qux");
k2s[keys[1]] = |std_string|_\("wmb");
k2s[keys[2]] = |std_string|_\("zxc");
char_reader r(keys[0]);
// positional arguments
BOOST_TEST_EQ('q', (r(true, k2s)));
BOOST_TEST_EQ('f', (r(false, k2s)));
// named arguments
r(_z = keys[1], _y = 1);
BOOST_TEST_EQ('m', (r(_z = k2s, _y = true)));
BOOST_TEST_EQ('a', (r(_z = k2s, _y = false)));
// deduced arguments
r(keys[2], 2);
BOOST_TEST_EQ('c', (r(k2s, true)));
BOOST_TEST_EQ('z', (r(k2s, false)));
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
* ``tag_namespace`` is the namespace in which the keywords used by the
function call operator resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
function body to determine the default value of all optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result\_ ## __LINE__ ## operator
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## operator
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params\_ ## __LINE__ ## operator
boost_param_parameters\_ ## __LINE__ ## operator;
template <typename A0, …, typename A ## **n**>
**result** operator()(
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters\_ ## __LINE__ ## operator::match<
A0, …, A ## **n**
>::type = boost_param_parameters\_ ## __LINE__ ## operator()
)
{
return this->boost_param_impl ## __LINE__ ## operator(
boost_param_parameters\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** operator()(
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters\_ ## __LINE__ ## operator::match<
A0, …, A ## **m**
>::type = boost_param_parameters\_ ## __LINE__ ## operator()
)
{
return this->boost_param_impl ## __LINE__ ## operator(
boost_param_parameters\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result\_ ## __LINE__ ## operator<Args>::type
boost_param_impl ## __LINE__ ## operator(Args const& args)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function call operator body.
.. |BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR(result, tag_ns, args)``
----------------------------------------------------------------------------
:Defined in: |preprocessor_header|_
Generates a function call operator that can take in positional arguments,
composed arguments, named arguments, and deduced arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Define the named parameters that will comprise the argument specification that
this macro will use. Ensure that all their tag types are in the same
namespace, which is ``kw`` in this case. The identifiers with leading
underscores can be passed to the bracket operator of ``args`` to extract the
same argument to which the corresponding named parameter (without underscores)
is bound, as will be shown later.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw) consume(rr))
Use the macro as a substitute for a normal ``const`` function call operator
header. Enclose the return type ``bool`` in parentheses. For each parameter,
also enclose the expected value type in parentheses. Since the value types
are mutually exclusive, you can wrap the parameters in a ``(deduced …)``
clause. Otherwise, just as with a normal function, the order in which you
specify the parameters determines their position. However, unlike a normal
function, default values must be specified within the function body. Also
within the function body, you must pass the matching identifier with the
leading underscore to the bracket operator of ``args`` to extract the
corresponding argument, but at least this doesn't require ``std::forward`` to
preserve value categories.
.. parsed-literal::
struct B
{
B()
{
}
BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), kw,
(deduced
(required
(lrc, (|std_bitset|_\<1>))
(lr, (|std_bitset|_\<2>))
)
(optional
(rrc, (|std_bitset|_\<3>))
(rr, (|std_bitset|_\<4>))
)
)
)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc0 | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr0 | rvalue_bitset<3>()]
)
);
return true;
}
};
The following function calls are legal.
.. parsed-literal::
B const b = B();
b( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
, rvalue_bitset<3>()
);
b( // positional arguments
lvalue_const_bitset<0>()
, lvalue_bitset<1>()
);
b(( // composed arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
));
b( // named arguments
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
b( // named arguments
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
Because the parameters were wrapped in a ``(deduced …)`` clause, the following
function calls are also legal.
.. parsed-literal::
b( // deduced arguments
rvalue_bitset<3>()
, lvalue_const_bitset<0>()
, lvalue_bitset<1>()
, rvalue_const_bitset<2>()
);
b( // deduced arguments
lvalue_bitset<1>()
, lvalue_const_bitset<0>()
);
The |preprocessor_cpp|_ test program demonstrates proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
* ``tag_namespace`` is the namespace in which the keywords used by the
function call operator resides.
* ``arguments`` is a |Boost_Preprocessor|_ `sequence`_ of
*argument-specifiers*, as defined below.
**Argument specifiers syntax:**
.. parsed-literal::
argument-specifiers ::= *specifier-group0* {*specifier-group0*\ }
specifier-group0 ::= *specifier-group1* |
(
'**(**' '**deduced**'
*specifier-group1* {*specifier-group1*\ }
'**)**'
)
specifier-group1 ::=
(
'**(**' '**optional**'
*specifier* {*specifier*\ }
'**)**'
) | (
'**(**' '**required**'
*specifier* {*specifier*\ }
'**)**'
)
specifier ::=
'**(**' *argument-name* '**,**' *restriction* ')'
restriction ::=
( '**\***' '**(**' *mfc* '**)**' ) |
( '**(**' *type-name* '**)**' ) |
'**\***'
* ``argument-name`` is any valid C++ identifier.
* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will
be the type of the corresponding ``argument-name``, whose second argument
will be the entire |ArgumentPack|_, and whose return type is a `Boolean
Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms
of ``previous-name ## _type``.
* ``type-name`` is either the name of a **target type** or an `MPL Binary
Metafunction Class`_ whose first argument will be the type of the
corresponding ``argument-name``, whose second argument will be the entire
|ArgumentPack|_, and whose return type is the **target type**.
Note that *specifier* does not include *default-value*. It is up to the
function body to determine the default value of all optional arguments.
**Approximate expansion:**
Where:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename Args>
using boost_param_result_const\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename Args>
struct boost_param_result_const\_ ## __LINE__ ## operator
{
typedef **result** type;
};
struct boost_param_params_const\_ ## __LINE__ ## operator
: |parameters|_\<
*list of parameter specifications, based on arguments*
>
{
};
typedef boost_param_params_const\_ ## __LINE__ ## operator
boost_param_parameters_const\_ ## __LINE__ ## operator;
template <typename A0, …, typename A ## **n**>
**result** operator()(
A0&& a0, …, A ## **n**\ && a ## **n**
, typename boost_param_parameters_const\_ ## __LINE__ ## operator
::match<A0, …, A ## **n**>::type
= boost_param_parameters_const\_ ## __LINE__ ## operator()
) const
{
return this->boost_param_impl_const ## __LINE__ ## operator(
boost_param_parameters_const\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **n**>(a ## **n**)
)
);
}
:vellipsis:`⋮`
template <typename A0, …, typename A ## **m**>
**result** operator()(
A0&& a0, …, A ## **m**\ && a ## **m**
, typename boost_param_parameters_const\_ ## __LINE__ ## operator
::match<A0, …, A ## **m**>::type
= boost_param_parameters_const\_ ## __LINE__ ## operator()
) const
{
return this->boost_param_impl_const ## __LINE__ ## operator(
boost_param_parameters_const\_ ## __LINE__ ## operator()(
|std_forward|_\<A0>(a0)
, …
, |std_forward|_\<A ## **m**>(a ## **m**)
)
);
}
template <typename Args>
typename boost_param_result_const\_ ## __LINE__ ## operator<Args>::type
boost_param_impl_const ## __LINE__ ## operator(Args const& args) const
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function call operator body.
.. |BOOST_PARAMETER_NO_SPEC_FUNCTION| replace:: ``BOOST_PARAMETER_NO_SPEC_FUNCTION``
.. _BOOST_PARAMETER_NO_SPEC_FUNCTION:
``BOOST_PARAMETER_NO_SPEC_FUNCTION(result, name)``
--------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a function that can take in named arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Named parameters are required when invoking the function; however, none of
their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw0) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw1) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw2) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw3) consume(rr))
Use the macro as a substitute for a variadic function header. Enclose the
return type ``bool`` in parentheses.
.. parsed-literal::
BOOST_PARAMETER_NO_SPEC_FUNCTION((bool), evaluate)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(args[_rr | rvalue_bitset<3>()])
);
return true;
}
To invoke the function, bind all its arguments to named parameters.
.. parsed-literal::
evaluate(
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
evaluate(
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
The |preproc_eval_cat_no_spec_cpp|_ test program demonstrates proper usage of
this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated implementation function.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename TaggedArg0, typename ...TaggedArgs>
using boost_param_no_spec_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename TaggedArg0, typename ...TaggedArgs>
struct boost_param_no_spec_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
);
template <typename TaggedArg0, typename ...TaggedArgs>
inline typename |boost_lazy_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
, boost_param_no_spec_result\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>
>::type
**name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args)
{
return boost_param_no_spec_impl ## __LINE__ ## **name**\ (
static_cast<
typename
boost_param_no_spec_result\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>::type(*)()
>(|std_nullptr|_\)
, |compose|_\(arg0, args...)
);
}
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION:
``BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION(result, name)``
---------------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a member function that can take in named arguments.
:Example usage:
When designing a front-end class template whose back-end is configurable via
parameterized inheritance, it can be useful to omit argument specifiers from
a named-parameter member function so that the delegate member functions of the
back-end classes can enforce their own specifications.
.. parsed-literal::
template <typename B>
struct frontend : B
{
frontend() : B()
{
}
BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((void), initialize)
{
this->initialize_impl(args);
}
};
Named parameters are required when invoking the member function; however, none
of their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(a0)
|BOOST_PARAMETER_NAME|_\(a1)
|BOOST_PARAMETER_NAME|_\(a2)
For this example, each of the back-end class templates requires its own
parameter to be present in the argument pack. In practice, such parameters
should be optional, with default values.
.. parsed-literal::
template <typename T>
class backend0
{
T a0;
public:
backend0() : a0()
{
}
T const& get_a0() const
{
return this->a0;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
this->a0 = args[_a0];
}
};
template <typename B, typename T>
class backend1 : public B
{
T a1;
public:
backend1() : B(), a1()
{
}
T const& get_a1() const
{
return this->a1;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
B::initialize_impl(args);
this->a1 = args[_a1];
}
};
template <typename B, typename T>
class backend2 : public B
{
T a2;
public:
backend2() : B(), a2()
{
}
T const& get_a2() const
{
return this->a2;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
B::initialize_impl(args);
this->a2 = args[_a2];
}
};
This example shows that while ``backend0`` must always be the root base class
template and that ``frontend`` must always be the most derived class template,
the other back-ends can be chained together in different orders.
.. parsed-literal::
char const* p = "foo";
frontend<
backend2<backend1<backend0<char const*>, char>, int>
> composed_obj0;
frontend<
backend1<backend2<backend0<char const*>, int>, char>
> composed_obj1;
composed_obj0.initialize(_a2 = 4, _a1 = ' ', _a0 = p);
composed_obj1.initialize(_a0 = p, _a1 = ' ', _a2 = 4);
BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
The |parameterized_inheritance_cpp|_ and |preproc_eval_cat_no_spec_cpp|_ test
programs demonstrate proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated implementation function. ``name`` may be qualified by the
``static`` keyword to declare the member function and its helpers as not
associated with any object of the enclosing type.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename TaggedArg0, typename ...TaggedArgs>
using boost_param_no_spec_result\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename TaggedArg0, typename ...TaggedArgs>
struct boost_param_no_spec_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
template <typename TaggedArg0, typename ...TaggedArgs>
inline typename |boost_lazy_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
, boost_param_no_spec_result\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>
>::type
**name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args)
{
return this->boost_param_no_spec_impl ## __LINE__ ## **name**\ (
static_cast<
typename
boost_param_no_spec_result\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>::type(*)()
>(|std_nullptr|_\)
, |compose|_\(arg0, args...)
);
}
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION| replace:: ``BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION``
.. _BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION:
``BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION(result, name)``
---------------------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a member function that can take in named arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Named parameters are required when invoking the member function; however, none
of their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw0) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw1) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw2) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw3) consume(rr))
Use the macro as a substitute for a variadic function header. Enclose the
return type ``bool`` in parentheses. The macro will qualify the function with
the ``const`` keyword.
.. parsed-literal::
struct D
{
D()
{
}
BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION((bool), evaluate_m)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr | rvalue_bitset<3>()]
)
);
return true;
}
};
To invoke the member function, bind all its arguments to named parameters.
.. parsed-literal::
D const d = D();
d.evaluate_m(
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
d.evaluate_m(
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
The |preproc_eval_cat_no_spec_cpp|_ test program demonstrates proper usage of
this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function.
* ``name`` is the base name of the function; it determines the name of the
generated implementation function.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename TaggedArg0, typename ...TaggedArgs>
using boost_param_no_spec_result_const\_ ## __LINE__ ## **name** = **result**;
// If **result** is a simple return type:
template <typename TaggedArg0, typename ...TaggedArgs>
struct boost_param_no_spec_result_const\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
template <typename TaggedArg0, typename ...TaggedArgs>
inline typename |boost_lazy_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
, boost_param_no_spec_result_const\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>
>::type
**name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args) const
{
return this->boost_param_no_spec_impl_const ## __LINE__ ## **name**\ (
static_cast<
typename
boost_param_no_spec_result_const\_ ## __LINE__ ## **name**\ <
TaggedArg0
, TaggedArgs...
>::type(*)()
>(|std_nullptr|_\)
, |compose|_\(arg0, args...)
);
}
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl_const ## __LINE__ ## **name**\ (
(ResultType(*)())
, Args const& args
) const
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR(result)``
----------------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a function call operator that can take in named arguments.
:Example usage:
When designing a front-end class template whose back-end is configurable via
parameterized inheritance, it can be useful to omit argument specifiers from
a named-parameter function call operator so that the delegate member functions
of the back-end classes can enforce their own specifications.
.. parsed-literal::
template <typename B>
struct frontend : B
{
frontend() : B()
{
}
BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR((void))
{
this->initialize_impl(args);
}
};
Named parameters are required when invoking the function call operator;
however, none of their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(a0)
|BOOST_PARAMETER_NAME|_\(a1)
|BOOST_PARAMETER_NAME|_\(a2)
For this example, each of the back-end class templates requires its own
parameter to be present in the argument pack. In practice, such parameters
should be optional, with default values.
.. parsed-literal::
template <typename T>
class backend0
{
T a0;
public:
backend0() : a0()
{
}
T const& get_a0() const
{
return this->a0;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
this->a0 = args[_a0];
}
};
template <typename B, typename T>
class backend1 : public B
{
T a1;
public:
backend1() : B(), a1()
{
}
T const& get_a1() const
{
return this->a1;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
B::initialize_impl(args);
this->a1 = args[_a1];
}
};
template <typename B, typename T>
class backend2 : public B
{
T a2;
public:
backend2() : B(), a2()
{
}
T const& get_a2() const
{
return this->a2;
}
protected:
template <typename ArgPack>
void initialize_impl(ArgPack const& args)
{
B::initialize_impl(args);
this->a2 = args[_a2];
}
};
This example shows that while ``backend0`` must always be the root base class
template and that ``frontend`` must always be the most derived class template,
the other back-ends can be chained together in different orders.
.. parsed-literal::
char const* p = "foo";
frontend<
backend2<backend1<backend0<char const*>, char>, int>
> composed_obj0;
frontend<
backend1<backend2<backend0<char const*>, int>, char>
> composed_obj1;
composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p);
composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4);
BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
The |parameterized_inheritance_cpp|_ and |preproc_eval_cat_no_spec_cpp|_ test
programs demonstrate proper usage of this macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename TaggedArg0, typename ...TaggedArgs>
using boost_param_no_spec_result\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename TaggedArg0, typename ...TaggedArgs>
struct boost_param_no_spec_result\_ ## __LINE__ ## operator
{
typedef **result** type;
};
template <typename TaggedArg0, typename ...TaggedArgs>
inline typename |boost_lazy_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
, boost_param_no_spec_result\_ ## __LINE__ ## operator<
TaggedArg0
, TaggedArgs...
>
>::type
operator()(TaggedArg0 const& arg0, TaggedArgs const&... args)
{
return this->boost_param_no_spec_impl ## __LINE__ ## operator(
static_cast<
typename
boost_param_no_spec_result\_ ## __LINE__ ## operator<
TaggedArg0
, TaggedArgs...
>::type(*)()
>(|std_nullptr|_\)
, |compose|_\(arg0, args...)
);
}
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
)
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR| replace:: ``BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR``
.. _BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR:
``BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR(result)``
----------------------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a function call operator that can take in named arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Named parameters are required when invoking the function call operator;
however, none of their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw0) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw1) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw2) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw3) consume(rr))
Use the macro as a substitute for a variadic function call operator
header. Enclose the return type ``bool`` in parentheses. The macro will
qualify the function with the ``const`` keyword.
.. parsed-literal::
struct D
{
D()
{
}
BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool))
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr | rvalue_bitset<3>()]
)
);
return true;
}
};
To invoke the function call operator, bind all its arguments to named
parameters.
.. parsed-literal::
D const d = D();
d(
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
d(
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
The |preproc_eval_cat_no_spec_cpp|_ test program demonstrates proper usage of this
macro.
**Macro parameters:**
* ``result`` is the parenthesized return type of the function call operator.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
// If **result** is a template instantiation of |boost_enable_if|_\,
// |boost_enable_if_c|_\, |boost_lazy_enable_if|_\,
// |boost_lazy_enable_if_c|_\, |boost_disable_if|_\, |boost_disable_if_c|_\,
// |boost_lazy_disable_if|_\, |boost_lazy_disable_if_c|_\, or
// |std_enable_if|_\:
template <typename TaggedArg0, typename ...TaggedArgs>
using boost_param_no_spec_result_const\_ ## __LINE__ ## operator = **result**;
// If **result** is a simple return type:
template <typename TaggedArg0, typename ...TaggedArgs>
struct boost_param_no_spec_result_const\_ ## __LINE__ ## operator
{
typedef **result** type;
};
template <typename TaggedArg0, typename ...TaggedArgs>
inline typename |boost_lazy_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
, boost_param_no_spec_result_const\_ ## __LINE__ ## operator<
TaggedArg0
, TaggedArgs...
>
>::type
operator()(
TaggedArg0 const& arg0
, TaggedArgs const&... args
) const
{
return this->boost_param_no_spec_impl_const ## __LINE__ ## operator(
static_cast<
typename
boost_param_no_spec_result_const\_ ## __LINE__ ## operator<
TaggedArg0
, TaggedArgs...
>::type(*)()
>(|std_nullptr|_\)
, |compose|_\(arg0, args...)
);
}
template <typename ResultType, typename Args>
ResultType
boost_param_no_spec_impl_const ## __LINE__ ## operator(
(ResultType(*)())
, Args const& args
) const
Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are
available for use within the function body.
.. |BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR| replace:: ``BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR``
.. _BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR:
``BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(cls, impl)``
--------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a constructor that can take in named arguments.
:Example usage:
When designing a front-end class template whose back-end is configurable via
parameterized inheritance, it can be useful to omit argument specifiers from
a named-parameter constructor so that the delegate constructors of the
back-end classes can enforce their own specifications.
.. parsed-literal::
template <typename B>
struct frontend : B
{
BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(frontend, (B))
};
Named parameters are required when invoking the constructor; however, none of
their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(a0)
|BOOST_PARAMETER_NAME|_\(a1)
|BOOST_PARAMETER_NAME|_\(a2)
For this example, each of the back-end class templates requires its own
parameter to be present in the argument pack. In practice, such parameters
should be optional, with default values.
.. parsed-literal::
struct _enabler
{
};
template <typename T>
class backend0
{
T a0;
public:
template <typename ArgPack>
explicit backend0(
ArgPack const& args
, typename |boost_enable_if|_\<
|is_argument_pack|_\<ArgPack>
, _enabler
>::type = _enabler()
) : a0(args[_a0])
{
}
T const& get_a0() const
{
return this->a0;
}
};
template <typename B, typename T>
class backend1 : public B
{
T a1;
public:
template <typename ArgPack>
explicit backend1(
ArgPack const& args
, typename |boost_enable_if|_\<
|is_argument_pack|_\<ArgPack>
, _enabler
>::type = _enabler()
) : B(args), a1(args[_a1])
{
}
T const& get_a1() const
{
return this->a1;
}
};
template <typename B, typename T>
class backend2 : public B
{
T a2;
public:
template <typename ArgPack>
explicit backend2(
ArgPack const& args
, typename |boost_enable_if|_\<
|is_argument_pack|_\<ArgPack>
, _enabler
>::type = _enabler()
) : B(args), a2(args[_a2])
{
}
T const& get_a2() const
{
return this->a2;
}
};
This example shows that while ``backend0`` must always be the root base class
template and that ``frontend`` must always be the most derived class template,
the other back-ends can be chained together in different orders.
.. parsed-literal::
char const* p = "foo";
frontend<
backend2<backend1<backend0<char const*>, char>, int>
> composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p);
frontend<
backend1<backend2<backend0<char const*>, int>, char>
> composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4);
BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
The |parameterized_inheritance_cpp|_ and |preproc_eval_cat_no_spec_cpp|_ test
programs demonstrate proper usage of this macro.
**Macro parameters:**
* ``cls`` is the name of the enclosing class.
* ``impl`` is the parenthesized implementation base class for ``cls``.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
template <
typename TaggedArg0
, typename ...TaggedArgs
, typename = typename |boost_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
>::type
>
inline explicit **cls**\ (
TaggedArg0 const& arg0
, TaggedArgs const&... args
) : **impl**\ (|compose|_\(arg0, args...))
{
}
.. |BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR| replace:: ``BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR``
.. _BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR:
``BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(cls, impl)``
----------------------------------------------------------
:Defined in: |preprocessor_no_spec_header|_
Generates a constructor that can take in named arguments.
:Example usage:
The return type of each of the following function templates falls under a
different value category.
.. parsed-literal::
template <std::size_t N>
|std_bitset|_\<N + 1> rvalue_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1> const rvalue_const_bitset()
{
return |std_bitset|_\<N + 1>();
}
template <std::size_t N>
|std_bitset|_\<N + 1>& lvalue_bitset()
{
static |std_bitset|_\<N + 1> lset = |std_bitset|_\<N + 1>();
return lset;
}
template <std::size_t N>
|std_bitset|_\<N + 1> const& lvalue_const_bitset()
{
static |std_bitset|_\<N + 1> const clset = |std_bitset|_\<N + 1>();
return clset;
}
The ``U::evaluate_category`` static member function template has a simple job:
to return the correct value category when passed in an object returned by one
of the functions defined above. Assume that
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined.
.. parsed-literal::
enum invoked
{
passed_by_lvalue_reference_to_const
, passed_by_lvalue_reference
, passed_by_rvalue_reference_to_const
, passed_by_rvalue_reference
};
struct U
{
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&)
{
return passed_by_lvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&)
{
return passed_by_lvalue_reference;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1> const&&)
{
return passed_by_rvalue_reference_to_const;
}
template <std::size_t N>
static invoked evaluate_category(|std_bitset|_\<N + 1>&&)
{
return passed_by_rvalue_reference;
}
};
Named parameters are required when invoking the constructor; however, none of
their tags need to be in the same namespace.
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\((_lrc, kw0) in(lrc))
|BOOST_PARAMETER_NAME|_\((_lr, kw1) in_out(lr))
|BOOST_PARAMETER_NAME|_\((_rrc, kw2) in(rrc))
|BOOST_PARAMETER_NAME|_\((_rr, kw3) consume(rr))
Unlike |BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|_, this macro doesn't require a
base class, only a delegate function to which the generated constructor can
pass its |ArgumentPack|_.
.. parsed-literal::
struct D
{
BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(D, D::_evaluate)
private:
template <typename Args>
static bool _evaluate(Args const& args)
{
BOOST_TEST_EQ(
passed_by_lvalue_reference_to_const
, U::evaluate_category<0>(args[_lrc])
);
BOOST_TEST_EQ(
passed_by_lvalue_reference
, U::evaluate_category<1>(args[_lr])
);
BOOST_TEST_EQ(
passed_by_rvalue_reference_to_const
, U::evaluate_category<2>(
args[_rrc | rvalue_const_bitset<2>()]
)
);
BOOST_TEST_EQ(
passed_by_rvalue_reference
, U::evaluate_category<3>(
args[_rr | rvalue_bitset<3>()]
)
);
return true;
}
};
To invoke the constructor, bind all its arguments to named parameters.
.. parsed-literal::
D dp0(
_rr0 = rvalue_bitset<3>()
, _lrc0 = lvalue_const_bitset<0>()
, _lr0 = lvalue_bitset<1>()
, _rrc0 = rvalue_const_bitset<2>()
);
D dp1(
_lr0 = lvalue_bitset<1>()
, _lrc0 = lvalue_const_bitset<0>()
);
The |preproc_eval_cat_no_spec_cpp|_ test program demonstrates proper usage of
this macro.
**Macro parameters:**
* ``cls`` is the name of the enclosing class.
* ``func`` is a function that takes in the |ArgumentPack|_ that the
generated constructor passes on.
**Argument specifiers syntax:**
None.
**Approximate expansion:**
.. parsed-literal::
template <
typename TaggedArg0
, typename ...TaggedArgs
, typename = typename |boost_enable_if|_\<
|are_tagged_arguments|_\<TaggedArg0,TaggedArgs...>
>::type
>
inline explicit **cls**\ (
TaggedArg0 const& arg0
, TaggedArgs const&... args
)
{
**func**\ (|compose|_\(arg0, args...));
}
.. |BOOST_PARAMETER_NAME| replace:: ``BOOST_PARAMETER_NAME``
.. _BOOST_PARAMETER_NAME:
``BOOST_PARAMETER_NAME(name)``
------------------------------
:Defined in: |name_header|_
Declares a tag-type and keyword object.
**If** *name* is of the form:
.. parsed-literal::
(*object-name*, *namespace-name*) *qualifier*\ (*tag-name*)
**then**
:Requires: *qualifier* is either ``in``, ``out``, ``in_out``, ``consume``,
``move_from``, or ``forward``.
:Expands to:
.. parsed-literal::
namespace *namespace-name* {
struct *tag-name*
{
static constexpr char const* keyword_name()
{
return ## *tag-name*;
}
typedef *unspecified* _;
typedef *unspecified* _1;
typedef boost::parameter::*qualifier* ## _reference qualifier;
// The following definitions are available only when
// |BOOST_PARAMETER_CAN_USE_MP11|_ is defined.
template <typename ArgumentPack>
using binding_fn = typename |binding|_\<
ArgumentPack
, *tag-name*
>::type;
template <typename ArgumentPack>
using fn = typename |value_type|_\<ArgumentPack, *tag-name*>::type;
};
}
|keyword|_\<*tag-namespace*::*tag-name*> const& *object-name*
= |keyword|_\<*tag-namespace*::*tag-name*>::instance;
**Else If** *name* is of the form:
.. parsed-literal::
(*tag-name*, *namespace-name*) *object-name*
**then**
Treats *name* as if it were of the form:
.. parsed-literal::
(forward(*tag-name*), *namespace-name*) *object-name*
**Else If** *name* is of the form:
.. parsed-literal::
*qualifier*\ (*tag-name*)
**then**
:Requires: *qualifier* is either ``in``, ``out``, ``in_out``, ``consume``,
``move_from``, or ``forward``.
:Expands to:
.. parsed-literal::
namespace tag {
struct *tag-name*
{
static constexpr char const* keyword_name()
{
return ## *tag-name*;
}
typedef *unspecified* _;
typedef *unspecified* _1;
typedef boost::parameter::*qualifier* ## _reference qualifier;
// The following definitions are available only when
// |BOOST_PARAMETER_CAN_USE_MP11|_ is defined.
template <typename ArgumentPack>
using binding_fn = typename |binding|_\<
ArgumentPack
, *tag-name*
>::type;
template <typename ArgumentPack>
using fn = typename |value_type|_\<ArgumentPack, *tag-name*>::type;
};
}
|keyword|_\<tag::*tag-name*> const& _ ## *tag-name*
= |keyword|_\<tag::*tag-name*>::instance;
**Else**
Treats *name* as if it were of the form:
.. parsed-literal::
forward(*tag-name*)
.. |BOOST_PARAMETER_NESTED_KEYWORD| replace:: ``BOOST_PARAMETER_NESTED_KEYWORD``
.. _BOOST_PARAMETER_NESTED_KEYWORD:
``BOOST_PARAMETER_NESTED_KEYWORD(tag_namespace, name, alias)``
--------------------------------------------------------------
:Defined in: |nested_keyword_header|_
Declares a tag-type, a keyword object, and an alias for that object nested in
the tag-type.
**If** *name* is of the form:
.. parsed-literal::
*qualifier*\ (*tag-name*)
**then**
:Requires: *qualifier* is either ``in``, ``out``, ``in_out``, ``consume``,
``move_from``, or ``forward``.
:Expands to:
.. parsed-literal::
namespace tag {
struct *tag-name*
{
static constexpr char const* keyword_name()
{
return ## *tag-name* ## _;
}
typedef *unspecified* _;
typedef *unspecified* _1;
typedef boost::parameter::*qualifier* ## _reference qualifier;
static |keyword|_\<*tag-name*> const& *alias*;
// The following definitions are available only when
// |BOOST_PARAMETER_CAN_USE_MP11|_ is defined.
template <typename ArgumentPack>
using binding_fn = typename |binding|_\<
ArgumentPack
, *tag-name*
>::type;
template <typename ArgumentPack>
using fn = typename |value_type|_\<ArgumentPack, *tag-name*>::type;
};
|keyword|_\<*tag-name*> const& tag::*tag-name*::*alias*
= |keyword|_\<*tag-name*>::instance;
}
|keyword|_\<tag::*tag-name*> const& tag::*tag-name*::*name*
= |keyword|_\<tag::*tag-name*>::instance;
**Else**
Treats *name* as if it were of the form:
.. parsed-literal::
forward(*tag-name*)
.. |BOOST_PARAMETER_TEMPLATE_KEYWORD| replace:: ``BOOST_PARAMETER_TEMPLATE_KEYWORD``
.. _BOOST_PARAMETER_TEMPLATE_KEYWORD:
``BOOST_PARAMETER_TEMPLATE_KEYWORD(name)``
------------------------------------------
:Defined in: |template_keyword_header|_
:Included by: |name_header|_
:Expands to:
.. parsed-literal::
namespace tag {
struct *name*;
}
template <typename T>
struct *name* : |template_keyword|_\<tag:: *name*, T>
{
};
The |function_type_tpl_param_cpp|_ test program demonstrates proper usage of
this macro.
.. |BOOST_PARAMETER_FUN| replace:: ``BOOST_PARAMETER_FUN``
.. _BOOST_PARAMETER_FUN:
``BOOST_PARAMETER_FUN(r, n, l, h, p)``
--------------------------------------
.. admonition:: Deprecated
This macro has been deprecated in favor of
``BOOST_PARAMETER_FUNCTION``.
Generates a sequence of `forwarding function`_ templates named
``n``, with arities ranging from ``l`` to ``h``, returning ``r``,
and using ``p`` to control overload resolution and assign tags to
positional arguments.
:Defined in: |macros_header|_
:Requires: ``l`` and ``h`` are nonnegative integer tokens
such that ``l`` < ``h``
:Expands to:
.. parsed-literal::
template <typename A1, typename A2, …, typename A ## **l**>
r
name(
A1 && a1, A2 && a2, …, A ## **l** && a ## **l**
, typename **p**::match<A1, A2, …, A ## **l**>::type p = **p**\ ()
)
{
return **name**\ _with_named_params(
**p**\ (
|std_forward|_\<A1>(a1)
, |std_forward|_\<A2>(a2)
, …
, |std_forward|_\<A ## **l**>(a ## **l**)
)
);
}
template <
typename A1
, typename A2
, …
, typename A ## **l**
, typename A ## |BOOST_PP_INC|_\ (**l**)
>
r
name(
A1 && a1, A2 && a2, …, A ## **l** && a ## **l**
, A ## |BOOST_PP_INC|_\ (**l**) const& a ## |BOOST_PP_INC|_\ (**l**)
, typename **p**::match<
A1, A2, …, A ## **l**, A ## |BOOST_PP_INC|_\ (**l**)
>::type p = **p**\ ()
)
{
return **name**\ _with_named_params(
**p**\ (
|std_forward|_\<A1>(a1)
, |std_forward|_\<A2>(a2)
, …
, |std_forward|_\<A ## **l**>(a ## **l**)
, |std_forward|_\<A ## |BOOST_PP_INC|_\ (**l**)>(
a ## |BOOST_PP_INC|_\ (**l**)
)
)
);
}
:vellipsis:`⋮`
template <typename A1, typename A2, …, typename A ## **h**>
r
name(
A1 && a1, A2 && a2, …, A ## **h** && x ## **h**
, typename **p**::match<A1, A2, …, A ## **h**>::type p = **p**\ ()
)
{
return **name**\ _with_named_params(
**p**\ (
|std_forward|_\<A1>(a1)
, |std_forward|_\<A2>(a2)
, …
, |std_forward|_\<A ## **h**>(a ## **h**)
)
);
}
The |macros_cpp|_ and |macros_eval_cat_cpp|_ test programs demonstrate proper
usage of this macro.
.. |BOOST_PARAMETER_KEYWORD| replace:: ``BOOST_PARAMETER_KEYWORD``
.. _BOOST_PARAMETER_KEYWORD:
``BOOST_PARAMETER_KEYWORD(n, k)``
---------------------------------
.. admonition:: Deprecated
This macro has been deprecated in favor of
``BOOST_PARAMETER_NAME``.
Generates the declaration of a |keyword tag type| named ``k`` in
namespace ``n`` and a corresponding |keyword object| definition in
the enclosing namespace.
:Defined in: |keyword_header|_
:Expands to:
.. parsed-literal::
namespace **n** {
struct **k**
{
static constexpr char const* keyword_name()
{
return ## *k*;
}
typedef *unspecified* _;
typedef *unspecified* _1;
typedef boost::parameter::forward_reference qualifier;
// The following definitions are available only when
// |BOOST_PARAMETER_CAN_USE_MP11|_ is defined.
template <typename ArgumentPack>
using binding_fn = typename |binding|_\<
ArgumentPack
, *k*
>::type;
template <typename ArgumentPack>
using fn = typename |value_type|_\<ArgumentPack, *k*>::type;
};
}
namespace {
|keyword|_\<*n*::**k**> const& **k**
= |keyword|_\<*n*::**k**>::instance;
}
``BOOST_PARAMETER_MATCH(p, a, x)``
----------------------------------
Generates a defaulted parameter declaration for a `forwarding function`_.
:Defined in: |match_header|_
:Requires: ``a`` is a `Boost.Preprocessor sequence`__ of the form
.. parsed-literal::
(A0)(A1)…(A ## *n*)
__ ../../../preprocessor/doc/data.html
:Expands to:
.. parsed-literal::
typename **p**::match<**A0**\ , **A1**\ , …, **A** ## *n*>::type
**x** = **p**\ ()
Configuration Macros
====================
.. |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING``
.. _BOOST_PARAMETER_HAS_PERFECT_FORWARDING:
``BOOST_PARAMETER_HAS_PERFECT_FORWARDING``
------------------------------------------
Determines whether or not the library supports perfect forwarding, or the
preservation of parameter value categories. Users can manually disable this
macro by ``#defining`` the |BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING|_
macro. Otherwise, the library will ``#define`` this macro if and only if it
is not already defined, and if the configuration macros
|BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, |BOOST_NO_SFINAE|_,
|BOOST_NO_CXX11_RVALUE_REFERENCES|_, |BOOST_NO_CXX11_VARIADIC_TEMPLATES|_, and
|BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS|_ are not already defined by
|Boost_Config|_.
:Defined in: |config_header|_
.. |BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING``
.. _BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING:
``BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING``
----------------------------------------------
It may be necessary to test user code in case perfect forwarding support is
unavailable. Users can ``#define`` this macro either in their project
settings or before including any library header files. Doing so will leave
both |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ undefined.
.. |BOOST_PARAMETER_CAN_USE_MP11| replace:: ``BOOST_PARAMETER_CAN_USE_MP11``
.. _BOOST_PARAMETER_CAN_USE_MP11:
``BOOST_PARAMETER_CAN_USE_MP11``
--------------------------------
Determines whether or not the library can use |Boost_MP11|_, a C++11
metaprogramming library. Users can manually disable this macro by
``#defining`` the |BOOST_PARAMETER_DISABLE_MP11_USAGE|_ macro or the
|BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING|_ macro. Otherwise, the library
will ``#define`` this macro if and only if it is not already defined, if
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is defined, and if the configuration
macros |BOOST_NO_CXX11_CONSTEXPR|_, |BOOST_NO_CXX11_DECLTYPE_N3276|_,
|BOOST_NO_CXX11_AUTO_DECLARATIONS|_, |BOOST_NO_CXX11_TEMPLATE_ALIASES|_,
|BOOST_NO_CXX11_STATIC_ASSERT|_, |BOOST_NO_CXX11_HDR_TYPE_TRAITS|_,
|BOOST_NO_CXX11_HDR_INITIALIZER_LIST|_, and |BOOST_NO_CXX11_HDR_TUPLE|_
are not already defined by |Boost_Config|_.
.. Admonition:: Usage Note
|Boost_MP11|_ and |Boost_MPL|_ are **not** mutually exclusive. It's
perfectly acceptable to specify deduced parameters using both quoted
metafunctions and metafunction classes, for example. See
|evaluate_category_cpp|_.
:Defined in: |config_header|_
:Example usage:
Given the following definitions:
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(x)
template <typename A0>
typename |boost_enable_if|_\<|std_is_same|_\<int,A0>,int>::type
sfinae(A0 const& a0)
{
return 0;
}
|Boost_MP11|_ allows deduced parameters to be defined more succinctly:
.. parsed-literal::
template <typename T, typename Args>
using predicate = |std_is_convertible|_\<T,char const*>;
|BOOST_PARAMETER_FUNCTION|_\((int), sfinae, tag,
(deduced
(optional
(x
, \*(|mp11_quote|_\<predicate>)
, static_cast<char const*>(|std_nullptr|_\)
)
)
)
)
{
return 1;
}
Without |Boost_MP11|_, deduced parameter definitions tend to be more verbose:
.. parsed-literal::
struct predicate
{
template <typename T, typename Args>
struct apply
: |mpl_if|_\<
|boost_is_convertible|_\<T,char const*>
, |mpl_true|_\ // Still have to convert to a
, |mpl_false|_\ // `Boolean Integral Constant`_.
>
{
};
};
|BOOST_PARAMETER_FUNCTION|_\((int), sfinae, tag,
(deduced
(optional
(x
, \*(predicate)
, static_cast<char const*>(|std_nullptr|_\)
)
)
)
)
{
return 1;
}
Either way, the following assertions will succeed:
.. parsed-literal::
assert(1 == sfinae());
assert(1 == sfinae("foo"));
assert(0 == sfinae(1));
As another example, given the following declarations and definitions:
.. parsed-literal::
|BOOST_PARAMETER_NAME|_\(x)
|BOOST_PARAMETER_NAME|_\(y)
template <typename E, typename Args>
void check0(E const& e, Args const& args);
template <typename P, typename E, typename ...Args>
void check(E const& e, Args const&... args)
{
check0(e, P()(args...));
}
Argument packs qualify as |Boost_MP11|_-style lists containing
|keyword tag type|\ s:
.. parsed-literal::
template <typename Args>
struct some_functor
{
template <typename K>
void operator()(K&&) const
{
// K is one of tag\:\:x, tag\:\:y, etc.
}
};
template <typename E, typename Args>
void check0(E const& e, Args const& args)
{
boost::mp11::mp_for_each<E>(some_functor<Args>());
}
The first check determines whether or not the argument type of ``_y`` is the
same as the reference type of ``_x``, while the second check determines
whether or not the argument type of ``_y`` is convertible to the value type of
``_x``. Here, it's possible to access the reference and value result types of
indexing an argument pack a little more directly:
.. parsed-literal::
// Use mp_bind on tag\:\:x\:\:binding_fn to access the reference type of _x.
check<
|parameters|_\<
tag\:\:x
, |optional|_\<
|deduced|_\<tag\:\:y>
, |mp11_bind|_\<
|std_is_same|_\ // |boost_is_same|_, standard version.
, |mp11_1|_\ // will be bound to the argument type of _y.
, |mp11_bind|_\<
tag\:\:x\:\:binding_fn
, |mp11_2|_\ // will be bound to the argument pack type.
>
>
>
>
>((_x = 0, _y = 1), 0, 1);
// Use mp_bind_q on tag\:\:x to access the value type of _x.
check<
|parameters|_\<
tag\:\:x
, |optional|_\<
|deduced|_\<tag\:\:y>
, |mp11_bind|_\<
|std_is_convertible|_\ // |boost_is_convertible|_, standard version.
, |mp11_1|_\ // will be bound to the argument type of _y.
, |mp11_bind_q|_\<
tag\:\:x
, |mp11_2|_\ // will be bound to the argument pack type.
>
>
>
>
>((_x = 0U, _y = 1U), 0U, 1U);
Argument packs still qualify as |Boost_MPL|_-style lists containing
|keyword tag type|\ s:
.. parsed-literal::
template <typename Args>
struct some_functor
{
template <typename K>
void operator()(K) const
{
// K is one of tag\:\:x, tag\:\:y, etc.
}
};
template <typename E, typename Args>
void check0(E const& e, Args const& args)
{
boost::mpl::for_each<E>(some_functor<Args>());
}
However, without |Boost_MP11|_, the corresponding checks become a little more
verbose:
.. parsed-literal::
check<
|parameters|_\<
tag\:\:x
, |optional|_\<
|deduced|_\<tag\:\:y>
, |mpl_if|_\<
|boost_is_same|_\<
|boost_add_lvalue_reference|_\<|mp11_1|_\>
, |binding|_\<|mp11_2|_\, tag\:\:x>
>
, |mpl_true|_\ // Still have to convert to a
, |mpl_false|_\ // `Boolean Integral Constant`_.
>
>
>
>((_x = 0, _y = 1), 0, 1);
// Use tag\:\:x\:\:_ or tag\:\:x\:\:_1 to access the value type of _x.
check<
|parameters|_\<
tag\:\:x
, |optional|_\<
|deduced|_\<tag\:\:y>
, |mpl_if|_\<
|boost_is_convertible|_\<|mp11_1|_\, tag\:\:x\:\:_1>
, |mpl_true|_\ // Still have to convert to a
, |mpl_false|_\ // `Boolean Integral Constant`_.
>
>
>
>((_x = 0U, _y = 1U), 0U, 1U);
The |singular_cpp|_, |compose_cpp|_, |optional_deduced_sfinae_cpp|_, and
|deduced_dep_pred_cpp|_ test programs demonstrate proper usage of this
macro.
.. |BOOST_PARAMETER_DISABLE_MP11_USAGE| replace:: ``BOOST_PARAMETER_DISABLE_MP11_USAGE``
.. _BOOST_PARAMETER_DISABLE_MP11_USAGE:
``BOOST_PARAMETER_DISABLE_MP11_USAGE``
--------------------------------------
It may be necessary to disable usage of |Boost_MP11|_ for compilers that
cannot support it. Users can ``#define`` this macro either in their project
settings or before including any library header files. Doing so will leave
|BOOST_PARAMETER_CAN_USE_MP11|_ undefined.
.. |BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE| replace:: ``BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE``
.. _BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE:
``BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE``
-----------------------------------------
If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is ``#defined``, then determines
the `MPL Variadic Sequence`_ underlying the nested ``parameter_spec`` type of
|parameters|. If the user does not manually ``#define`` this macro, then the
library will ``#define`` it as |mp11_list|_ if
|BOOST_PARAMETER_CAN_USE_MP11|_ is defined, |fusion_list|_ if
|BOOST_FUSION_HAS_VARIADIC_LIST|_ is defined (by |Boost_Fusion|_),
|fusion_deque|_ if |BOOST_FUSION_HAS_VARIADIC_DEQUE|_ is defined
(by |Boost_Fusion|_), or |mpl_vector|_ otherwise.
:Example:
.. parsed-literal::
#define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE |fusion_vector|_
:Defined in: |parameters_header|_
.. |BOOST_PARAMETER_MAX_ARITY| replace:: ``BOOST_PARAMETER_MAX_ARITY``
.. _BOOST_PARAMETER_MAX_ARITY:
``BOOST_PARAMETER_MAX_ARITY``
-----------------------------
If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is ``#defined``, then:
* If the `MPL Variadic Sequence`_ underlying the nested ``parameter_spec``
type of |parameters| does not have a size limit--which is the case with
|mp11_list|_, |fusion_list|_, and |fusion_deque|_, but not
|mpl_vector|_--then this macro can be safely ignored. User code that
manually defines |BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE|_ should also
manually define this macro to the size limit of the sequence if it has
one.
If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is **not** ``#defined``, then:
* Mutable references must be wrapped by |boost_ref|_ or |std_ref|_ if passed
by position to Boost.Parameter-enabled functions with arity greater than
or equal to |BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY|_.
:Defined in: |config_header|_
:Default Value: |BOOST_MPL_LIMIT_VECTOR_SIZE|_ (defined by |Boost_MPL|_) if
perfect forwarding is supported, ``8`` otherwise.
:Minimum Value: ``2``
:Maximum Value: |BOOST_PARAMETER_COMPOSE_MAX_ARITY|_
.. |BOOST_PARAMETER_COMPOSE_MAX_ARITY| replace:: ``BOOST_PARAMETER_COMPOSE_MAX_ARITY``
.. _BOOST_PARAMETER_COMPOSE_MAX_ARITY:
``BOOST_PARAMETER_COMPOSE_MAX_ARITY``
-------------------------------------
If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is **not** ``#defined``, then
determines the maximum number of arguments supported by the |compose| function
and by the |BOOST_PARAMETER_NO_SPEC_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION|_,
|BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR|_,
|BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR|_,
|BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|_, and
|BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR|_ code generation macros.
:Defined in: |config_header|_
:Default Value: ``20`` for a few older compilers, ``64`` otherwise
:Minimum Value: ``2``
.. |BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY| replace:: ``BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY``
.. _BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY:
``BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY``
--------------------------------------------------------
If this library does **not** support perfect forwarding, determines the number
of arguments less than which |parameters| generates an exponential number of
function call operator overloads, and greater than or equal to which
|parameters| does not. Will only be ``#defined`` by the library if it is
not already ``#defined`` and |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ is
**not** ``#defined``.
:Defined in: |config_header|_
:Default Value: ``0``
:Minimum Value: ``0``
...Outside Of This Library
--------------------------
#. If |Boost_Config|_ defines the macro
|BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, then the macros
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined; otherwise, the
code generation macros would not work correctly.
#. If |Boost_Config|_ defines the macro |BOOST_NO_SFINAE|_, then the macros
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined; otherwise, keyword
types generated by |BOOST_PARAMETER_NAME|_ and
|BOOST_PARAMETER_NESTED_KEYWORD|_ would not work correctly.
#. If |Boost_Config|_ defines the macro
|BOOST_NO_CXX11_RVALUE_REFERENCES|_, then the macros
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_VARIADIC_TEMPLATES|_,
then the macros |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro
|BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS|_, then the macros
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_ and
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_CONSTEXPR|_, then the
macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_DECLTYPE_N3276|_,
then the macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_AUTO_DECLARATIONS|_,
then the macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_TEMPLATE_ALIASES|_,
then the macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_STATIC_ASSERT|_, then
the macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_HDR_TYPE_TRAITS|_,
then the macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro
|BOOST_NO_CXX11_HDR_INITIALIZER_LIST|_, then the macro
|BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Config|_ defines the macro |BOOST_NO_CXX11_HDR_TUPLE|_, then the
macro |BOOST_PARAMETER_CAN_USE_MP11|_ will be left undefined.
#. If |Boost_Fusion|_ defines the macro |BOOST_FUSION_HAS_VARIADIC_LIST|_,
if this library defines the macro
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_, and if
|BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE|_ is left undefined, then the
`MPL Variadic Sequence`_ underlying the nested ``parameter_spec`` type of
|parameters| will be |fusion_list|_.
#. If |Boost_Fusion|_ defines the macro |BOOST_FUSION_HAS_VARIADIC_DEQUE|_,
if this library defines the macro
|BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_, and if
|BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE|_ is left undefined, then the
`MPL Variadic Sequence`_ underlying the nested ``parameter_spec`` type of
|parameters| will be |fusion_deque|_.
#. The value that |Boost_MPL|_ defines the macro
|BOOST_MPL_LIMIT_VECTOR_SIZE|_ as will be the value that this library
defines the macro |BOOST_PARAMETER_MAX_ARITY|_ as if this library defines
the macro |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|_.
Tutorial
========
Follow `this link`__ to the Boost.Parameter tutorial documentation.
__ index.html#tutorial
//////////////////////////////////////////////////////////////////////////////
.. [#thread] References to tag objects may be initialized multiple
times. This scenario can only occur in the presence of
threading. Because the C++ standard doesn't consider threading,
it doesn't explicitly allow or forbid multiple initialization of
references. That said, it's hard to imagine an implementation
where it could make a difference.
.. [#no_result_of] Where |BOOST_NO_RESULT_OF|_ is ``#defined``,
|boost_result_of|_\ ``<F()>::type`` is replaced by ``F::result_type``.
.. |std_nullptr| replace:: std::nullptr
.. _std_nullptr: http://en.cppreference.com/w/cpp/language/nullptr
.. |std_forward| replace:: std::forward
.. _std_forward: http://en.cppreference.com/w/cpp/utility/forward
.. |std_enable_if| replace:: std::enable_if
.. _std_enable_if: http://en.cppreference.com/w/cpp/types/enable_if
.. |std_is_convertible| replace:: std::is_convertible
.. _std_is_convertible: http://en.cppreference.com/w/cpp/types/is_convertible
.. |std_is_same| replace:: std::is_same
.. _std_is_same: http://en.cppreference.com/w/cpp/types/is_same
.. |std_ref| replace:: ``std::ref``
.. _std_ref: http://en.cppreference.com/w/cpp/utility/functional/ref
.. |std_map| replace:: std::map
.. _std_map: http://en.cppreference.com/w/cpp/container/map
.. |std_string| replace:: std::string
.. _std_string: http://en.cppreference.com/w/cpp/string/basic_string
.. |std_bitset| replace:: std::bitset
.. _std_bitset: http://en.cppreference.com/w/cpp/utility/bitset
.. |Boost_Config| replace:: Boost.Config
.. _Boost_Config: ../../../config/doc/html/index.html
.. |BOOST_NO_FUNCTION_TEMPLATE_ORDERING| replace:: ``BOOST_NO_FUNCTION_TEMPLATE_ORDERING``
.. _BOOST_NO_FUNCTION_TEMPLATE_ORDERING: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__03_defects
.. |BOOST_NO_SFINAE| replace:: ``BOOST_NO_SFINAE``
.. _BOOST_NO_SFINAE: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__03_defects
.. |BOOST_NO_CXX11_AUTO_DECLARATIONS| replace:: ``BOOST_NO_CXX11_AUTO_DECLARATIONS``
.. _BOOST_NO_CXX11_AUTO_DECLARATIONS: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_CONSTEXPR| replace:: ``BOOST_NO_CXX11_CONSTEXPR``
.. _BOOST_NO_CXX11_CONSTEXPR: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_DECLTYPE_N3276| replace:: ``BOOST_NO_CXX11_DECLTYPE_N3276``
.. _BOOST_NO_CXX11_DECLTYPE_N3276: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS| replace:: ``BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS``
.. _BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_HDR_INITIALIZER_LIST| replace:: ``BOOST_NO_CXX11_HDR_INITIALIZER_LIST``
.. _BOOST_NO_CXX11_HDR_INITIALIZER_LIST: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_HDR_TUPLE| replace:: ``BOOST_NO_CXX11_HDR_TUPLE``
.. _BOOST_NO_CXX11_HDR_TUPLE: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_HDR_TYPE_TRAITS| replace:: ``BOOST_NO_CXX11_HDR_TYPE_TRAITS``
.. _BOOST_NO_CXX11_HDR_TYPE_TRAITS: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_RVALUE_REFERENCES| replace:: ``BOOST_NO_CXX11_RVALUE_REFERENCES``
.. _BOOST_NO_CXX11_RVALUE_REFERENCES: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_STATIC_ASSERT| replace:: ``BOOST_NO_CXX11_STATIC_ASSERT``
.. _BOOST_NO_CXX11_STATIC_ASSERT: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_TEMPLATE_ALIASES| replace:: ``BOOST_NO_CXX11_TEMPLATE_ALIASES``
.. _BOOST_NO_CXX11_TEMPLATE_ALIASES: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |BOOST_NO_CXX11_VARIADIC_TEMPLATES| replace:: ``BOOST_NO_CXX11_VARIADIC_TEMPLATES``
.. _BOOST_NO_CXX11_VARIADIC_TEMPLATES: ../../../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
.. |Boost_Preprocessor| replace:: Boost.Preprocessor
.. _Boost_Preprocessor: ../../../preprocessor/doc/index.html
.. _`sequence`: ../../../preprocessor/doc/data/sequences.html
.. |BOOST_PP_INC| replace:: BOOST_PP_INC
.. _BOOST_PP_INC: ../../../preprocessor/doc/ref/inc.html
.. |boost_enable_if| replace:: boost::enable_if
.. _boost_enable_if: ../../../core/doc/html/core/enable_if.html
.. |boost_enable_if_c| replace:: boost::enable_if_c
.. _boost_enable_if_c: ../../../core/doc/html/core/enable_if.html
.. |boost_lazy_enable_if| replace:: boost::lazy_enable_if
.. _boost_lazy_enable_if: ../../../core/doc/html/core/enable_if.html
.. |boost_lazy_enable_if_c| replace:: boost::lazy_enable_if_c
.. _boost_lazy_enable_if_c: ../../../core/doc/html/core/enable_if.html
.. |boost_disable_if| replace:: boost::disable_if
.. _boost_disable_if: ../../../core/doc/html/core/enable_if.html
.. |boost_disable_if_c| replace:: boost::disable_if_c
.. _boost_disable_if_c: ../../../core/doc/html/core/enable_if.html
.. |boost_lazy_disable_if| replace:: boost::lazy_disable_if
.. _boost_lazy_disable_if: ../../../core/doc/html/core/enable_if.html
.. |boost_lazy_disable_if_c| replace:: boost::lazy_disable_if_c
.. _boost_lazy_disable_if_c: ../../../core/doc/html/core/enable_if.html
.. |boost_ref| replace:: ``boost::ref``
.. _boost_ref: ../../../core/doc/html/core/ref.html
.. |BOOST_NO_RESULT_OF| replace:: ``BOOST_NO_RESULT_OF``
.. _BOOST_NO_RESULT_OF: ../../../utility/utility.htm#BOOST_NO_RESULT_OF
.. |boost_result_of| replace:: ``boost::result_of``
.. _boost_result_of: ../../../utility/utility.htm#result_of
.. |boost_is_const| replace:: boost::is_const
.. _boost_is_const: ../../../type_traits/doc/html/boost_typetraits/is_const.html
.. |boost_is_convertible| replace:: boost::is_convertible
.. _boost_is_convertible: ../../../type_traits/doc/html/boost_typetraits/is_convertible.html
.. |boost_is_same| replace:: boost::is_same
.. _boost_is_same: ../../../type_traits/doc/html/boost_typetraits/is_same.html
.. |boost_is_scalar| replace:: boost::is_scalar
.. _boost_is_scalar: ../../../type_traits/doc/html/boost_typetraits/is_scalar.html
.. |boost_add_lvalue_reference| replace:: boost::add_lvalue_reference
.. _boost_add_lvalue_reference: ../../../type_traits/doc/html/boost_typetraits/add_lvalue_reference.html
.. |boost_remove_reference| replace:: boost::remove_reference
.. _boost_remove_reference: ../../../type_traits/doc/html/boost_typetraits/remove_reference.html
.. |Boost_MPL| replace:: Boost.MPL
.. _Boost_MPL: ../../../mpl/doc/index.html
.. _`Metafunction`: ../../../mpl/doc/refmanual/metafunction.html
.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html
.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html
.. _`MPL Forward Sequence`: ../../../mpl/doc/refmanual/forward-sequence.html
.. _`MPL Associative Sequence`: ../../../mpl/doc/refmanual/associative-sequence.html
.. _`MPL Variadic Sequence`: ../../../mpl/doc/refmanual/variadic-sequence.html
.. |BOOST_MPL_LIMIT_VECTOR_SIZE| replace:: ``BOOST_MPL_LIMIT_VECTOR_SIZE``
.. _BOOST_MPL_LIMIT_VECTOR_SIZE: ../../../mpl/doc/refmanual/limit-vector-size.html
.. |mpl_eval_if| replace:: boost::mpl::eval_if
.. _mpl_eval_if: ../../../mpl/doc/refmanual/eval-if.html
.. |mpl_true| replace:: mpl::true\_
.. _mpl_true: ../../../mpl/doc/refmanual/bool.html
.. |mpl_false| replace:: mpl::false\_
.. _mpl_false: ../../../mpl/doc/refmanual/bool.html
.. |mpl_if| replace:: mpl::if\_
.. _mpl_if: ../../../mpl/doc/refmanual/if.html
.. |mpl_vector| replace:: ``boost::mpl::vector``
.. _mpl_vector: ../../../mpl/doc/refmanual/vector.html
.. |Boost_MP11| replace:: Boost.MP11
.. _Boost_MP11: ../../../mp11/doc/html/mp11.html
.. |mp11_quote| replace:: boost::mp11::mp_quote
.. _mp11_quote: ../../../mp11/doc/html/mp11.html#mp_quotef
.. |mp11_1| replace:: boost::mp11::_1
.. _mp11_1: ../../../mp11/doc/html/mp11.html#1_9
.. |mp11_2| replace:: boost::mp11::_2
.. _mp11_2: ../../../mp11/doc/html/mp11.html#1_9
.. |mp11_bind| replace:: boost::mp11::mp_bind
.. _mp11_bind: ../../../mp11/doc/html/mp11.html#mp_bindf_t
.. |mp11_bind_q| replace:: boost::mp11::mp_bind_q
.. _mp11_bind_q: ../../../mp11/doc/html/mp11.html#mp_bind_qq_t
.. |mp11_list| replace:: ``boost::mp11::mp_list``
.. _mp11_list: ../../../mp11/doc/html/mp11.html#mp_listt
.. |Boost_Fusion| replace:: Boost.Fusion
.. _Boost_Fusion: ../../../fusion/doc/html/index.html
.. |BOOST_FUSION_HAS_VARIADIC_DEQUE| replace:: ``BOOST_FUSION_HAS_VARIADIC_DEQUE``
.. _BOOST_FUSION_HAS_VARIADIC_DEQUE: ../../../../boost/fusion/container/deque/deque_fwd.hpp
.. |BOOST_FUSION_HAS_VARIADIC_LIST| replace:: ``BOOST_FUSION_HAS_VARIADIC_LIST``
.. _BOOST_FUSION_HAS_VARIADIC_LIST: ../../../../boost/fusion/container/list/list_fwd.hpp
.. |fusion_vector| replace:: ``boost::fusion::vector``
.. _fusion_vector: ../../../fusion/doc/html/fusion/container/vector.html
.. |fusion_deque| replace:: ``boost::fusion::deque``
.. _fusion_deque: ../../../fusion/doc/html/fusion/container/deque.html
.. |fusion_list| replace:: ``boost::fusion::list``
.. _fusion_list: ../../../fusion/doc/html/fusion/container/list.html
.. |config_header| replace:: boost/parameter/config.hpp
.. _config_header: ../../../../boost/parameter/config.hpp
.. |binding_header| replace:: boost/parameter/binding.hpp
.. _binding_header: ../../../../boost/parameter/binding.hpp
.. |value_type_header| replace:: boost/parameter/value_type.hpp
.. _value_type_header: ../../../../boost/parameter/value_type.hpp
.. |are_tagged_arguments_header| replace:: boost/parameter/are_tagged_arguments.hpp
.. _are_tagged_arguments_header: ../../../../boost/parameter/are_tagged_arguments.hpp
.. |is_argument_pack_header| replace:: boost/parameter/is_argument_pack.hpp
.. _is_argument_pack_header: ../../../../boost/parameter/is_argument_pack.hpp
.. |template_keyword_header| replace:: boost/parameter/template_keyword.hpp
.. _template_keyword_header: ../../../../boost/parameter/template_keyword.hpp
.. |keyword_header| replace:: boost/parameter/keyword.hpp
.. _keyword_header: ../../../../boost/parameter/keyword.hpp
.. |name_header| replace:: boost/parameter/name.hpp
.. _name_header: ../../../../boost/parameter/name.hpp
.. |nested_keyword_header| replace:: boost/parameter/nested_keyword.hpp
.. _nested_keyword_header: ../../../../boost/parameter/nested_keyword.hpp
.. |compose_header| replace:: boost/parameter/compose.hpp
.. _compose_header: ../../../../boost/parameter/compose.hpp
.. |preprocessor_no_spec_header| replace:: boost/parameter/preprocessor_no_spec.hpp
.. _preprocessor_no_spec_header: ../../../../boost/parameter/preprocessor_no_spec.hpp
.. |required_header| replace:: boost/parameter/required.hpp
.. _required_header: ../../../../boost/parameter/required.hpp
.. |optional_header| replace:: boost/parameter/optional.hpp
.. _optional_header: ../../../../boost/parameter/optional.hpp
.. |deduced_header| replace:: boost/parameter/deduced.hpp
.. _deduced_header: ../../../../boost/parameter/deduced.hpp
.. |parameters_header| replace:: boost/parameter/parameters.hpp
.. _parameters_header: ../../../../boost/parameter/parameters.hpp
.. |match_header| replace:: boost/parameter/match.hpp
.. _match_header: ../../../../boost/parameter/match.hpp
.. |macros_header| replace:: boost/parameter/macros.hpp
.. _macros_header: ../../../../boost/parameter/macros.hpp
.. |preprocessor_header| replace:: boost/parameter/preprocessor.hpp
.. _preprocessor_header: ../../../../boost/parameter/preprocessor.hpp
.. |function_type_tpl_param_cpp| replace:: function_type_tpl_param.cpp
.. _function_type_tpl_param_cpp: ../../test/function_type_tpl_param.cpp
.. |ntp_cpp| replace:: test/ntp.cpp
.. _ntp_cpp: ../../test/ntp.cpp
.. |singular_cpp| replace:: singular.cpp
.. _singular_cpp: ../../test/singular.cpp
.. |compose_cpp| replace:: compose.cpp
.. _compose_cpp: ../../test/compose.cpp
.. |evaluate_category_cpp| replace:: evaluate_category.cpp
.. _evaluate_category_cpp: ../../test/evaluate_category.cpp
.. |parameterized_inheritance_cpp| replace:: parameterized_inheritance.cpp
.. _parameterized_inheritance_cpp: ../../test/parameterized_inheritance.cpp
.. |preproc_eval_cat_no_spec_cpp| replace:: preprocessor_eval_cat_no_spec.cpp
.. _preproc_eval_cat_no_spec_cpp: ../../test/preprocessor_eval_cat_no_spec.cpp
.. |preprocessor_eval_cat_cpp| replace:: preprocessor_eval_category.cpp
.. _preprocessor_eval_cat_cpp: ../../test/preprocessor_eval_category.cpp
.. |preprocessor_eval_cat_8_cpp| replace:: preprocessor_eval_cat_8.cpp
.. _preprocessor_eval_cat_8_cpp: ../../test/preprocessor_eval_cat_8.cpp
.. |optional_deduced_sfinae_cpp| replace:: optional_deduced_sfinae.cpp
.. _optional_deduced_sfinae_cpp: ../../test/optional_deduced_sfinae.cpp
.. |mpl_cpp| replace:: mpl.cpp
.. _mpl_cpp: ../../test/mpl.cpp
.. |preprocessor_cpp| replace:: preprocessor.cpp
.. _preprocessor_cpp: ../../test/preprocessor.cpp
.. |preprocessor_deduced_cpp| replace:: preprocessor_deduced.cpp
.. _preprocessor_deduced_cpp: ../../test/preprocessor_deduced.cpp
.. |deduced_dep_pred_cpp| replace:: deduced_dependent_predicate.cpp
.. _deduced_dep_pred_cpp: ../../test/deduced_dependent_predicate.cpp
.. |macros_eval_cat_cpp| replace:: macros_eval_category.cpp
.. _macros_eval_cat_cpp: ../../test/macros_eval_category.cpp
.. |macros_cpp| replace:: macros.cpp
.. _macros_cpp: ../../test/macros.cpp