Compare commits

...

53 Commits

Author SHA1 Message Date
nobody
fe43dad724 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Daniel Wallin
ce2d43c1b5 Merged HEAD to RC_1_34_0
[SVN r37582]
2007-05-03 14:39:42 +00:00
nobody
86d7201a99 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r37579]
2007-05-03 14:11:06 +00:00
Dave Abrahams
ccf40a29c1 Correct testing bugs:
either changing assert(...) or BOOST_ASSERT(...) to BOOST_TEST
    (in my code only)

    or adding "return boost::report_errors();" where it was clearly
    missing (and a pure bug, in anyone's code).

    or changing BOOST_TEST to BOOST_CHECK where the integer library
    was clearly using Boost.Test and not returning report_errors().


[SVN r37063]
2007-02-25 15:28:02 +00:00
Dave Abrahams
28ed7b9704 fix table styles
[SVN r36573]
2007-01-03 17:12:34 +00:00
Dave Abrahams
6c3ee189d1 replace "write something here"
[SVN r36569]
2007-01-03 16:45:10 +00:00
Rene Rivera
15048a1d82 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Daniel Wallin
3852ff760c merged HEAD to RC
[SVN r35452]
2006-10-02 23:37:18 +00:00
Daniel Wallin
916b4d2c2f merged HEAD to RC
[SVN r35405]
2006-09-29 00:31:28 +00:00
Daniel Wallin
af9b04e7ad merged HEAD to RC
[SVN r35364]
2006-09-28 13:11:46 +00:00
Daniel Wallin
894dffe6ff merged HEAD to RC
[SVN r35360]
2006-09-28 10:22:54 +00:00
Daniel Wallin
c17ea8d26d merged HEAD to RC
[SVN r35357]
2006-09-27 20:59:14 +00:00
Daniel Wallin
1844c27699 Merged HEAD to RC.
[SVN r35339]
2006-09-26 14:49:52 +00:00
Markus Schöpflin
9694b76bf2 Merged python header inclusion fix from trunk.
[SVN r35320]
2006-09-25 10:49:42 +00:00
Daniel Wallin
7c9ddf23e0 merged HEAD to RC
[SVN r35300]
2006-09-23 22:53:35 +00:00
Daniel Wallin
224d313a05 Merged HEAD to RC.
[SVN r35285]
2006-09-23 10:41:14 +00:00
Daniel Wallin
47c53efbaa merged HEAD to RC
[SVN r35260]
2006-09-21 17:33:28 +00:00
nobody
57ef2b6ee9 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35259]
2006-09-21 17:29:16 +00:00
Dave Abrahams
297e85c0f1 fix license
[SVN r35232]
2006-09-20 17:34:41 +00:00
Dave Abrahams
3a59d2cea3 merged from HEAD
[SVN r35231]
2006-09-20 17:30:10 +00:00
Daniel Wallin
58bb633dc0 Merged HEAD to RC.
[SVN r35228]
2006-09-20 15:05:46 +00:00
nobody
3397bafb4a This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35227]
2006-09-20 15:03:36 +00:00
Daniel Wallin
cc256f0bb3 Merged HEAD to RC
[SVN r35215]
2006-09-19 18:23:18 +00:00
Dave Abrahams
e3b060b3e5 merged from HEAD
[SVN r35207]
2006-09-19 15:34:02 +00:00
Daniel Wallin
0791667e33 Merged HEAD to RC
[SVN r35197]
2006-09-19 13:13:43 +00:00
Daniel Wallin
91ffd43483 Merged changes from HEAD to RC.
[SVN r35195]
2006-09-19 11:51:07 +00:00
nobody
fa751e022e This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35193]
2006-09-19 11:47:55 +00:00
Daniel Wallin
1f6c9a3034 Merged changes from HEAD to RC_1_34_0.
[SVN r35183]
2006-09-18 20:54:56 +00:00
nobody
6c209395aa This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35179]
2006-09-18 20:47:47 +00:00
Daniel Wallin
5231f04b27 Merged changes from head to RC_1_34_0.
[SVN r35177]
2006-09-18 20:42:44 +00:00
nobody
c7258e9c9e This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35173]
2006-09-18 20:05:46 +00:00
nobody
22a1f905e9 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35170]
2006-09-18 19:56:20 +00:00
Dave Abrahams
0417a36693 merged from HEAD
[SVN r35163]
2006-09-18 18:11:49 +00:00
Dave Abrahams
d42b860b8d Sun workarounds
[SVN r35137]
2006-09-16 18:15:08 +00:00
Dave Abrahams
c5168be5d7 Parameter library Workarounds for Borland and MSVC
Parameter library explicit markup for expected failures

value_init.hpp:
  Borland workarounds
  Use angle-includes consistently


[SVN r35085]
2006-09-13 03:15:16 +00:00
Dave Abrahams
c29a75c9df merged from trunk
[SVN r35083]
2006-09-13 00:40:00 +00:00
Dave Abrahams
e18d621508 Add missing license/copyright
[SVN r35070]
2006-09-11 22:27:29 +00:00
nobody
40399d3505 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35043]
2006-09-08 09:38:01 +00:00
Daniel Wallin
d6db8c6216 Merged name.hpp from HEAD.
[SVN r34945]
2006-08-24 21:13:51 +00:00
Daniel Wallin
38817a8bb5 fixed missing include
[SVN r34941]
2006-08-24 16:19:14 +00:00
Dave Abrahams
646c519dc0 merged from trunk
[SVN r34930]
2006-08-23 13:01:56 +00:00
Daniel Wallin
cb501f9f38 merged changes from HEAD
[SVN r34921]
2006-08-22 17:36:58 +00:00
Dave Abrahams
7eb7737095 merged from trunk
[SVN r34918]
2006-08-22 14:01:34 +00:00
Daniel Wallin
bfc5811fdc Merged HEAD to RC_1_34_0.
[SVN r34899]
2006-08-16 22:34:35 +00:00
Daniel Wallin
1f8f44b26c Merged changes from HEAD to RC_1_34_0.
[SVN r34898]
2006-08-16 22:30:07 +00:00
Dave Abrahams
6729c38504 Borland workaround
[SVN r34808]
2006-08-02 19:07:09 +00:00
Dave Abrahams
cf5d2c46f5 Workarounds for Borland
[SVN r34805]
2006-08-02 16:16:36 +00:00
nobody
49e928273d This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r34788]
2006-07-30 21:33:23 +00:00
Gennaro Prota
00bbfbb20c boost guidelines (mainly from inspect tool: tabs, license reference text, etc.); more to do...
[SVN r34753]
2006-07-27 11:48:49 +00:00
Dave Abrahams
ca120a3f04 merged from trunk
[SVN r34696]
2006-07-24 14:38:01 +00:00
Dave Abrahams
e2b452c1f4 merged from trunk
[SVN r34290]
2006-06-12 20:00:14 +00:00
Rene Rivera
6695f76c5f [merge from head] Allow keywords to be copyable and default constructable, to facilitate use of keywords outside of Boost.Parameter.
[SVN r33691]
2006-04-13 20:12:20 +00:00
nobody
bf25a637c8 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
48 changed files with 9486 additions and 2783 deletions

View File

@@ -1,3 +1,6 @@
# Copyright David Abrahams 2006. 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)
import docutils ;
import path ;
@@ -13,7 +16,7 @@ for local b in $(bases)
html $(b) : $(b).rst :
#
<docutils-html>"-gdt --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
<docutils-html>"-gdt --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
;
}

File diff suppressed because it is too large Load Diff

781
doc/html/python.html Normal file
View File

@@ -0,0 +1,781 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title>The Boost Parameter Library Python Binding Documentation</title>
<meta name="authors" content="Daniel Wallin" />
<meta name="organization" content="Boost Consulting" />
<meta name="date" content="2006-09-21" />
<meta name="copyright" content="Copyright David Abrahams, Daniel Wallin 2005. 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)" />
<link rel="stylesheet" href="rst.css" type="text/css" />
</head>
<body>
<div class="document" id="the-boost-parameter-library-python-binding-documentation">
<h1 class="title">The Boost Parameter Library Python Binding Documentation</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Authors:</th>
<td>Daniel Wallin</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference" href="mailto:dalwan01&#64;student.umu.se">dalwan01&#64;student.umu.se</a></td></tr>
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first last reference" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2006-09-21</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Daniel Wallin
2005. Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td></tr>
</tbody>
</table>
<div class="abstract topic">
<p class="topic-title first">Abstract</p>
<p>Makes it possible to bind Boost.Parameter-enabled
functions, operators and constructors to Python.</p>
</div>
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#introduction" id="id8" name="id8">Introduction</a></li>
<li><a class="reference" href="#tutorial" id="id9" name="id9">Tutorial</a></li>
<li><a class="reference" href="#concept-parameterspec" id="id10" name="id10">concept <span class="concept">ParameterSpec</span></a></li>
<li><a class="reference" href="#special-keywords" id="id11" name="id11"><em>special</em> keywords</a></li>
<li><a class="reference" href="#class-template-init" id="id12" name="id12">class template <tt class="docutils literal"><span class="pre">init</span></tt></a></li>
<li><a class="reference" href="#class-template-call" id="id13" name="id13">class template <tt class="docutils literal"><span class="pre">call</span></tt></a></li>
<li><a class="reference" href="#class-template-function" id="id14" name="id14">class template <tt class="docutils literal"><span class="pre">function</span></tt></a></li>
<li><a class="reference" href="#function-template-def" id="id15" name="id15">function template <tt class="docutils literal"><span class="pre">def</span></tt></a></li>
<li><a class="reference" href="#portability" id="id16" name="id16">Portability</a></li>
</ul>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id8" id="introduction" name="introduction">Introduction</a></h1>
<p><tt class="docutils literal"><span class="pre">boost/parameter/python.hpp</span></tt> introduces a group of <a class="reference" href="../../../python/doc/v2/def_visitor.html"><tt class="docutils literal"><span class="pre">def_visitors</span></tt></a> that can
be used to easily expose Boost.Parameter-enabled member functions to Python with
Boost.Python. It also provides a function template <tt class="docutils literal"><span class="pre">def()</span></tt> that can be used
to expose Boost.Parameter-enabled free functions.</p>
<p>When binding a Boost.Parameter enabled function, the keyword tags
must be specified. Additionally, because Boost.Parameter enabled
functions are templates, the desired function signature must be
specified.</p>
<!-- The keyword tags are specified as an `MPL Sequence`_, using the
pointer qualifications described in |ParameterSpec|_ below. The
signature is also specifid as an `MPL sequence`_ of parameter
types. Additionally, ``boost::parameter::python::function`` and
``boost::parameter::python::def`` requires a class with forwarding
overloads. We will take a closer look at how this is done in the
tutorial section below. -->
<p>The keyword tags and associated argument types are specified as an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL
Sequence</a>, using the function type syntax described in <a class="reference" href="#concept-parameterspec"><span class="concept">ParameterSpec</span></a>
below. Additionally, <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> and
<tt class="docutils literal"><span class="pre">boost::parameter::python::def</span></tt> requires a class with forwarding overloads.
We will take a closer look at how this is done in the tutorial section below.</p>
<!-- The last two sentences are terribly vague. Which namespace is -->
<!-- ``function`` in? Isn't the return type always needed? What -->
<!-- else are we going to do other than pass these sequences to -->
<!-- function? -->
</div>
<div class="section">
<h1><a class="toc-backref" href="#id9" id="tutorial" name="tutorial">Tutorial</a></h1>
<p>In this section we will outline the steps needed to bind a simple
Boost.Parameter-enabled member function to Python. Knowledge of the
Boost.Parameter <a class="reference" href="index.html">macros</a> are required to understand this section.</p>
<p>The class and member function we are interested in binding looks
like this:</p>
<pre class="literal-block">
#include &lt;boost/parameter/keyword.hpp&gt;
#include &lt;boost/parameter/preprocessor.hpp&gt;
#include &lt;boost/parameter/python.hpp&gt;
#include &lt;boost/python.hpp&gt;
// First the keywords
BOOST_PARAMETER_KEYWORD(tag, title)
BOOST_PARAMETER_KEYWORD(tag, width)
BOOST_PARAMETER_KEYWORD(tag, height)
class window
{
public:
BOOST_PARAMETER_MEMBER_FUNCTION(
(void), open, tag,
(required (title, (std::string)))
(optional (width, (unsigned), 400)
(height, (unsigned), 400))
)
{
<em>… function implementation …</em>
}
};
</pre>
<!-- @example.prepend('#include <cassert>') -->
<!-- @example.replace_emphasis('''
assert(title == "foo");
assert(height == 20);
assert(width == 400);
''') -->
<p>It defines a set of overloaded member functions called <tt class="docutils literal"><span class="pre">open</span></tt> with one
required parameter and two optional ones. To bind this member function to
Python we use the binding utility <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt>.
<tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> is a <a class="reference" href="../../../python/doc/v2/def_visitor.html"><tt class="docutils literal"><span class="pre">def_visitor</span></tt></a> that we'll instantiate
and pass to <tt class="docutils literal"><span class="pre">boost::python::class_::def()</span></tt>.</p>
<p>To use <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> we first need to define
a class with forwarding overloads.</p>
<pre class="literal-block">
struct open_fwd
{
template &lt;class A0, class A1, class A2&gt;
void operator()(
boost::type&lt;void&gt;, window&amp; self
, A0 const&amp; a0, A1 const&amp; a1, A2 const&amp; a2
)
{
self.open(a0, a1, a2);
}
};
</pre>
<p>The first parameter, <tt class="docutils literal"><span class="pre">boost::type&lt;void&gt;</span></tt>, tells the forwarding overload
what the return type should be. In this case we know that it's always void
but in some cases, when we are exporting several specializations of a
Boost.Parameter-enabled template, we need to use that parameter to
deduce the return type.</p>
<p><tt class="docutils literal"><span class="pre">window::open()</span></tt> takes a total of 3 parameters, so the forwarding function
needs to take three parameters as well.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">We only need one overload in the forwarding class, despite the
fact that there are two optional parameters. There are special
circumstances when several overload are needed; see
<a class="reference" href="#special-keywords">special keywords</a>.</p>
</div>
<p>Next we'll define the module and export the class:</p>
<pre class="literal-block">
BOOST_PYTHON_MODULE(my_module)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_&lt;window&gt;(&quot;window&quot;)
.def(
&quot;open&quot;, py::function&lt;
open_fwd
, mpl::vector&lt;
void
, tag::title(std::string)
, tag::width*(unsigned)
, tag::height*(unsigned)
&gt;
&gt;()
);
}
</pre>
<!-- @jam_prefix.append('import python ;') -->
<!-- @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') -->
<!-- @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
, howmany = 'all'
) -->
<!-- @del jam_prefix[:] -->
<p><tt class="docutils literal"><span class="pre">py::function</span></tt> is passed two parameters. The first one is the class with
forwarding overloads that we defined earlier. The second one is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL
Sequence</a> with the keyword tag types and argument types for the function
specified as function types. The pointer syntax used in <tt class="docutils literal"><span class="pre">tag::width*</span></tt> and
<tt class="docutils literal"><span class="pre">tag::height*</span></tt> means that the parameter is optional. The first element of
the <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a> is the return type of the function, in this case <tt class="docutils literal"><span class="pre">void</span></tt>.</p>
<!-- The
pointer syntax means that the parameter is optional, so in this case
``width`` and ``height`` are optional parameters. The third parameter
is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
then the parameter types:
.. parsed-literal::
mpl::vector<void, std::string, unsigned, unsigned>
*return type* *title* *width* *height*
.. @ignore() -->
<p>That's it! This class can now be used in Python with the expected syntax:</p>
<pre class="literal-block">
&gt;&gt;&gt; w = my_module.window()
&gt;&gt;&gt; w.open(title = &quot;foo&quot;, height = 20)
</pre>
<!-- @example.prepend('import my_module') -->
<!-- @run_python(module_path = my_module) -->
<!-- Sorry to say this at such a late date, but this syntax really -->
<!-- strikes me as cumbersome. Couldn't we do something like:
class_<window>("window")
.def(
"open",
(void (*)(
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned))
)0
);
or at least:
class_<window>("window")
.def(
"open",
mpl::vector<
void,
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned)
>()
);
assuming, that is, that we will have to repeat the tags (yes,
users of broken compilers will have to give us function pointer
types instead). -->
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id10" id="concept-parameterspec" name="concept-parameterspec">concept <span class="concept">ParameterSpec</span></a></h1>
<p>A <span class="concept">ParameterSpec</span> is a function type <tt class="docutils literal"><span class="pre">K(T)</span></tt> that describes both the keyword tag,
<tt class="docutils literal"><span class="pre">K</span></tt>, and the argument type, <tt class="docutils literal"><span class="pre">T</span></tt>, for a parameter.</p>
<p><tt class="docutils literal"><span class="pre">K</span></tt> is either:</p>
<ul class="simple">
<li>A <em>required</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag</span></tt></li>
<li><strong>or</strong>, an <em>optional</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag*</span></tt></li>
<li><strong>or</strong>, a <em>special</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag**</span></tt></li>
</ul>
<p>where <tt class="docutils literal"><span class="pre">Tag</span></tt> is a keyword tag type, as used in a specialization
of <a class="reference" href="../../../parameter/doc/html/reference.html#keyword"><tt class="docutils literal"><span class="pre">boost::parameter::keyword</span></tt></a>.</p>
<p>The <strong>arity range</strong> for an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a> of <span class="concept">ParameterSpec</span>'s is
defined as the closed range:</p>
<pre class="literal-block">
[ mpl::size&lt;S&gt; - number of <em>special</em> keyword tags in <tt class="docutils literal"><span class="pre">S</span></tt>, mpl::size&lt;S&gt; ]
</pre>
<p>For example, the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2&lt;x(int),y(int)&gt;</span></tt> is <tt class="docutils literal"><span class="pre">[2,2]</span></tt>,
the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2&lt;x(int),y*(int)&gt;</span></tt> is <tt class="docutils literal"><span class="pre">[2,2]</span></tt> and the
<strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2&lt;x(int),y**(int)&gt;</span></tt> is <tt class="docutils literal"><span class="pre">[1,2]</span></tt>.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id11" id="special-keywords" name="special-keywords"><em>special</em> keywords</a></h1>
<p>Sometimes it is desirable to have a default value for a parameter that differ
in type from the parameter. This technique is useful for doing simple tag-dispatching
based on the presence of a parameter. An <a class="reference" href="index.html#dispatching-based-on-the-presence-of-a-default">example</a> of this is given in the Boost.Parameter
docs. The example uses a different technique, but could also have been written like this:</p>
<pre class="literal-block">
namespace core
{
template &lt;class ArgumentPack&gt;
void dfs_dispatch(ArgumentPack const&amp; args, mpl::false_)
{
<em>…compute and use default color map…</em>
}
template &lt;class ArgumentPack, class ColorMap&gt;
void dfs_dispatch(ArgumentPack const&amp; args, ColorMap colormap)
{
<em>…use colormap…</em>
}
}
template &lt;class ArgumentPack&gt;
void depth_first_search(ArgumentPack const&amp; args)
{
core::dfs_dispatch(args, args[color | mpl::false_()]);
}
</pre>
<!-- @example.prepend('''
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/mpl/bool.hpp>
#include <cassert>
BOOST_PARAMETER_KEYWORD(tag, color);
typedef boost::parameter::parameters<tag::color> params;
namespace mpl = boost::mpl;
''') -->
<!-- @example.replace_emphasis('''
assert(args[color | 1] == 1);
''') -->
<!-- @example.replace_emphasis('''
assert(args[color | 1] == 0);
''') -->
<!-- @example.append('''
int main()
{
depth_first_search(params()());
depth_first_search(params()(color = 0));
}''') -->
<!-- @build() -->
<p>In the above example the type of the default for <tt class="docutils literal"><span class="pre">color</span></tt> is <tt class="docutils literal"><span class="pre">mpl::false_</span></tt>, a
type that is distinct from any color map that the user might supply.</p>
<p>When binding the case outlined above, the default type for <tt class="docutils literal"><span class="pre">color</span></tt> will not
be convertible to the parameter type. Therefore we need to tag the <tt class="docutils literal"><span class="pre">color</span></tt>
keyword as a <em>special</em> keyword. By doing this we tell the binding functions
that it needs to generate two overloads, one with the <tt class="docutils literal"><span class="pre">color</span></tt> parameter
present and one without. Had there been two <em>special</em> keywords, four
overloads would need to be generated. The number of generated overloads is
equal to 2<sup>N</sup>, where <tt class="docutils literal"><span class="pre">N</span></tt> is the number of <em>special</em> keywords.</p>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id12" id="class-template-init" name="class-template-init">class template <tt class="docutils literal"><span class="pre">init</span></tt></a></h1>
<p>Defines a named parameter enabled constructor.</p>
<pre class="literal-block">
template &lt;class ParameterSpecs&gt;
struct init : python::def_visitor&lt;init&lt;ParameterSpecs&gt; &gt;
{
template &lt;class Class&gt;
void def(Class&amp; class_);
template &lt;class CallPolicies&gt;
<em>def_visitor</em> operator[](CallPolicies const&amp; policies) const;
};
</pre>
<!-- @ignore() -->
<div class="section">
<h2><a id="init-requirements" name="init-requirements"><tt class="docutils literal"><span class="pre">init</span></tt> requirements</a></h2>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element is a
model of <span class="concept">ParameterSpec</span>.</p>
</li>
<li><p class="first">For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity
range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>, <tt class="docutils literal"><span class="pre">Class</span></tt> must support these
expressions:</p>
<table border="1" class="docutils table">
<colgroup>
<col width="30%" />
<col width="17%" />
<col width="53%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><p class="first last">Expression</p>
</th>
<th class="head"><p class="first last">Return type</p>
</th>
<th class="head"><p class="first last">Requirements</p>
</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">Class(a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
</td>
<td><p class="first last">-</p>
</td>
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt><tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
<div class="section">
<h2><a id="template-class-callpolicies-operator-callpolicies-const" name="template-class-callpolicies-operator-callpolicies-const"><tt class="docutils literal"><span class="pre">template</span> <span class="pre">&lt;class</span> <span class="pre">CallPolicies&gt;</span> <span class="pre">operator[](CallPolicies</span> <span class="pre">const&amp;)</span></tt></a></h2>
<p>Returns a <tt class="docutils literal"><span class="pre">def_visitor</span></tt> equivalent to <tt class="docutils literal"><span class="pre">*this</span></tt>, except that it
uses CallPolicies when creating the binding.</p>
</div>
<div class="section">
<h2><a id="id3" name="id3">Example</a></h2>
<pre class="literal-block">
#include &lt;boost/parameter/keyword.hpp&gt;
#include &lt;boost/parameter/preprocessor.hpp&gt;
#include &lt;boost/parameter/python.hpp&gt;
#include &lt;boost/python.hpp&gt;
#include &lt;boost/mpl/vector.hpp&gt;
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
struct base
{
template &lt;class ArgumentPack&gt;
base(ArgumentPack const&amp; args)
{
<em>… use args …</em>
}
};
class X : base
{
public:
BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
(required (x, *))
(optional (y, *))
)
};
BOOST_PYTHON_MODULE(<em>module name</em>)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_&lt;X&gt;(&quot;X&quot;, no_init)
.def(
py::init&lt;
mpl::vector&lt;tag::x(int), tag::y*(int)&gt;
&gt;()
);
}
</pre>
<!-- @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
''') -->
<!-- @example.replace_emphasis('my_module') -->
<!-- @jam_prefix.append('import python ;') -->
<!-- @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') -->
<!-- @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
) -->
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id13" id="class-template-call" name="class-template-call">class template <tt class="docutils literal"><span class="pre">call</span></tt></a></h1>
<p>Defines a <tt class="docutils literal"><span class="pre">__call__</span></tt> operator, mapped to <tt class="docutils literal"><span class="pre">operator()</span></tt> in C++.</p>
<pre class="literal-block">
template &lt;class ParameterSpecs&gt;
struct call : python::def_visitor&lt;call&lt;ParameterSpecs&gt; &gt;
{
template &lt;class Class&gt;
void def(Class&amp; class_);
template &lt;class CallPolicies&gt;
<em>def_visitor</em> operator[](CallPolicies const&amp; policies) const;
};
</pre>
<!-- @ignore() -->
<div class="section">
<h2><a id="call-requirements" name="call-requirements"><tt class="docutils literal"><span class="pre">call</span></tt> requirements</a></h2>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
except the first models <span class="concept">ParameterSpec</span>. The first element
is the result type of <tt class="docutils literal"><span class="pre">c(…)</span></tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">Class</span></tt> must support these expressions, where <tt class="docutils literal"><span class="pre">c</span></tt> is an
instance of <tt class="docutils literal"><span class="pre">Class</span></tt>:</p>
<table border="1" class="docutils table">
<colgroup>
<col width="24%" />
<col width="26%" />
<col width="50%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><p class="first last">Expression</p>
</th>
<th class="head"><p class="first last">Return type</p>
</th>
<th class="head"><p class="first last">Requirements</p>
</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">c(a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
</td>
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
</td>
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt><tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
</td>
</tr>
</tbody>
</table>
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id4" name="id4"><tt class="docutils literal"><span class="pre">template</span> <span class="pre">&lt;class</span> <span class="pre">CallPolicies&gt;</span> <span class="pre">operator[](CallPolicies</span> <span class="pre">const&amp;)</span></tt></a></h2>
<p>Returns a <tt class="docutils literal"><span class="pre">def_visitor</span></tt> equivalent to <tt class="docutils literal"><span class="pre">*this</span></tt>, except that it
uses CallPolicies when creating the binding.</p>
</div>
<div class="section">
<h2><a id="id5" name="id5">Example</a></h2>
<pre class="literal-block">
#include &lt;boost/parameter/keyword.hpp&gt;
#include &lt;boost/parameter/preprocessor.hpp&gt;
#include &lt;boost/parameter/python.hpp&gt;
#include &lt;boost/python.hpp&gt;
#include &lt;boost/mpl/vector.hpp&gt;
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
namespace parameter = boost::parameter;
typedef parameter::parameters&lt;
parameter::required&lt;tag::x&gt;
, parameter::optional&lt;tag::y&gt;
&gt; call_parameters;
class X
{
public:
template &lt;class ArgumentPack&gt;
int call_impl(ArgumentPack const&amp; args)
{
<em>… use args …</em>
}
template &lt;class A0&gt;
int operator()(A0 const&amp; a0)
{
return call_impl(call_parameters()(a0));
}
template &lt;class A0, class A1&gt;
int operator()(A0 const&amp; a0, A1 const&amp; a1)
{
return call_impl(call_parameters()(a0,a1));
}
};
BOOST_PYTHON_MODULE(<em>module name</em>)
{
using namespace boost::python;
namespace py = parameter::python;
namespace mpl = boost::mpl;
class_&lt;X&gt;(&quot;X&quot;)
.def(
py::call&lt;
mpl::vector&lt;int, tag::x(int), tag::y*(int)&gt;
&gt;()
);
}
</pre>
<!-- @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
return 0;
''') -->
<!-- @example.replace_emphasis('my_module') -->
<!-- @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
) -->
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id14" id="class-template-function" name="class-template-function">class template <tt class="docutils literal"><span class="pre">function</span></tt></a></h1>
<p>Defines a named parameter enabled member function.</p>
<pre class="literal-block">
template &lt;class Fwd, class ParameterSpecs&gt;
struct function : python::def_visitor&lt;function&lt;Fwd, ParameterSpecs&gt; &gt;
{
template &lt;class Class, class Options&gt;
void def(Class&amp; class_, char const* name, Options const&amp; options);
};
</pre>
<!-- @ignore() -->
<div class="section">
<h2><a id="function-requirements" name="function-requirements"><tt class="docutils literal"><span class="pre">function</span></tt> requirements</a></h2>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
except the first models <span class="concept">ParameterSpec</span>. The first element
is the result type of <tt class="docutils literal"><span class="pre">c.f(…)</span></tt>, where <tt class="docutils literal"><span class="pre">f</span></tt> is the member
function.</p>
</li>
<li><p class="first">An instance of <tt class="docutils literal"><span class="pre">Fwd</span></tt> must support this expression:</p>
<table border="1" class="docutils table">
<colgroup>
<col width="39%" />
<col width="18%" />
<col width="43%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><p class="first last">Expression</p>
</th>
<th class="head"><p class="first last">Return type</p>
</th>
<th class="head"><p class="first last">Requirements</p>
</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">fwd(boost::type&lt;R&gt;(),</span> <span class="pre">self,</span> <span class="pre">a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
</td>
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
</td>
<td><p class="first last"><tt class="docutils literal"><span class="pre">self</span></tt> is a reference to the object on which
the function should be invoked. <tt class="docutils literal"><span class="pre">a0</span></tt><tt class="docutils literal"><span class="pre">aN</span></tt>
are tagged arguments.</p>
</td>
</tr>
</tbody>
</table>
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id6" name="id6">Example</a></h2>
<p>This example exports a member function <tt class="docutils literal"><span class="pre">f(int</span> <span class="pre">x,</span> <span class="pre">int</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">…)</span></tt> to Python. The
sequence of <span class="concept">ParameterSpec</span>'s <tt class="docutils literal"><span class="pre">mpl::vector2&lt;tag::x(int),</span> <span class="pre">tag::y*(int)&gt;</span></tt> has
an <strong>arity range</strong> of [2,2], so we only need one forwarding overload.</p>
<pre class="literal-block">
#include &lt;boost/parameter/keyword.hpp&gt;
#include &lt;boost/parameter/preprocessor.hpp&gt;
#include &lt;boost/parameter/python.hpp&gt;
#include &lt;boost/python.hpp&gt;
#include &lt;boost/mpl/vector.hpp&gt;
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
class X
{
public:
BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
(required (x, *))
(optional (y, *, 1))
)
{
<em></em>
}
};
struct f_fwd
{
template &lt;class A0, class A1&gt;
void operator()(boost::type&lt;void&gt;, X&amp; self, A0 const&amp; a0, A1 const&amp; a1)
{
self.f(a0, a1);
}
};
BOOST_PYTHON_MODULE(<em>module name</em>)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_&lt;X&gt;(&quot;X&quot;)
.def(&quot;f&quot;,
py::function&lt;
f_fwd
, mpl::vector&lt;void, tag::x(int), tag::y*(int)&gt;
&gt;()
);
}
</pre>
<!-- @example.replace_emphasis('''
assert(x == 0);
assert(y == 1);
''') -->
<!-- @example.replace_emphasis('my_module') -->
<!-- @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
) -->
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id15" id="function-template-def" name="function-template-def">function template <tt class="docutils literal"><span class="pre">def</span></tt></a></h1>
<p>Defines a named parameter enabled free function in the current Python scope.</p>
<pre class="literal-block">
template &lt;class Fwd, class ParameterSpecs&gt;
void def(char const* name);
</pre>
<!-- @ignore() -->
<div class="section">
<h2><a id="def-requirements" name="def-requirements"><tt class="docutils literal"><span class="pre">def</span></tt> requirements</a></h2>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
except the first models <span class="concept">ParameterSpec</span>. The first element
is the result type of <tt class="docutils literal"><span class="pre">f(…)</span></tt>, where <tt class="docutils literal"><span class="pre">f</span></tt> is the function.</p>
</li>
<li><p class="first">An instance of <tt class="docutils literal"><span class="pre">Fwd</span></tt> must support this expression:</p>
<table border="1" class="docutils table">
<colgroup>
<col width="39%" />
<col width="21%" />
<col width="40%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><p class="first last">Expression</p>
</th>
<th class="head"><p class="first last">Return type</p>
</th>
<th class="head"><p class="first last">Requirements</p>
</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">fwd(boost::type&lt;R&gt;(),</span> <span class="pre">a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
</td>
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
</td>
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt><tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
</td>
</tr>
</tbody>
</table>
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id7" name="id7">Example</a></h2>
<p>This example exports a function <tt class="docutils literal"><span class="pre">f(int</span> <span class="pre">x,</span> <span class="pre">int</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">…)</span></tt> to Python. The
sequence of <span class="concept">ParameterSpec</span>'s <tt class="docutils literal"><span class="pre">mpl::vector2&lt;tag::x(int),</span> <span class="pre">tag::y*(int)&gt;</span></tt> has
an <strong>arity range</strong> of [2,2], so we only need one forwarding overload.</p>
<pre class="literal-block">
BOOST_PARAMETER_FUNCTION((void), f, tag,
(required (x, *))
(optional (y, *, 1))
)
{
<em></em>
}
struct f_fwd
{
template &lt;class A0, class A1&gt;
void operator()(boost::type&lt;void&gt;, A0 const&amp; a0, A1 const&amp; a1)
{
f(a0, a1);
}
};
BOOST_PYTHON_MODULE(…)
{
def&lt;
f_fwd
, mpl::vector&lt;
void, tag::x(int), tag::y*(int)
&gt;
&gt;(&quot;f&quot;);
}
</pre>
<!-- @ignore() -->
<!-- again, the undefined ``fwd`` identifier. -->
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id16" id="portability" name="portability">Portability</a></h1>
<p>The Boost.Parameter Python binding library requires <em>partial template
specialization</em>.</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2007-01-03 17:02 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -3,97 +3,109 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title>The Boost Parameter Library Reference Documentation</title>
<meta name="authors" content="David Abrahams Daniel Wallin" />
<meta name="organization" content="Boost Consulting" />
<meta name="date" content="2005-07-17" />
<meta name="copyright" content="Copyright David Abrahams, Daniel Wallin 2005. 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)" />
<link rel="stylesheet" href="rst.css" type="text/css" />
</head>
<body>
<div class="document" id="the-boost-parameter-library-reference-documentation">
<h1 class="title">The Boost Parameter Library Reference Documentation</h1>
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Daniel Wallin</td>
</tr>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:dalwan01&#64;student.umu.se">dalwan01&#64;student.umu.se</a></td>
</tr>
<tr class="field"><th class="field-name">organization:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date: 2005/07/17 19:53:01 $</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Daniel Wallin
<tr><th class="docinfo-name">Authors:</th>
<td>David Abrahams
<br />Daniel Wallin</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="last reference" href="mailto:dalwan01&#64;student.umu.se">dalwan01&#64;student.umu.se</a></td></tr>
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first last reference" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2005-07-17</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Daniel Wallin
2005. Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
</tr>
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td></tr>
</tbody>
</table>
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
<hr class="docutils" />
<div class="contents topic" id="contents">
<p class="topic-title first"><a name="contents">Contents</a></p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#preliminaries" id="id24" name="id24">1&nbsp;&nbsp;&nbsp;Preliminaries</a><ul class="auto-toc">
<li><a class="reference" href="#namespaces" id="id25" name="id25">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></li>
<li><a class="reference" href="#exceptions" id="id26" name="id26">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></li>
<li><a class="reference" href="#thread-safety" id="id27" name="id27">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></li>
<li><a class="reference" href="#typography" id="id28" name="id28">1.4&nbsp;&nbsp;&nbsp;Typography</a></li>
<li><a class="reference" href="#preliminaries" id="id30" name="id30">1&nbsp;&nbsp;&nbsp;Preliminaries</a><ul class="auto-toc">
<li><a class="reference" href="#namespaces" id="id31" name="id31">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></li>
<li><a class="reference" href="#exceptions" id="id32" name="id32">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></li>
<li><a class="reference" href="#thread-safety" id="id33" name="id33">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></li>
<li><a class="reference" href="#typography" id="id34" name="id34">1.4&nbsp;&nbsp;&nbsp;Typography</a></li>
</ul>
</li>
<li><a class="reference" href="#terminology" id="id29" name="id29">2&nbsp;&nbsp;&nbsp;Terminology</a></li>
<li><a class="reference" href="#concepts" id="id30" name="id30">3&nbsp;&nbsp;&nbsp;Concepts</a><ul class="auto-toc">
<li><a class="reference" href="#argumentpack" id="id31" name="id31">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></li>
<li><a class="reference" href="#id5" id="id32" name="id32">3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></li>
<li><a class="reference" href="#terminology" id="id35" name="id35">2&nbsp;&nbsp;&nbsp;Terminology</a></li>
<li><a class="reference" href="#concepts" id="id36" name="id36">3&nbsp;&nbsp;&nbsp;Concepts</a><ul class="auto-toc">
<li><a class="reference" href="#argumentpack" id="id37" name="id37">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></li>
<li><a class="reference" href="#id5" id="id38" name="id38">3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></li>
</ul>
</li>
<li><a class="reference" href="#class-templates" id="id33" name="id33">4&nbsp;&nbsp;&nbsp;Class Templates</a><ul class="auto-toc">
<li><a class="reference" href="#id7" id="id34" name="id34">4.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">keyword</span></tt></a></li>
<li><a class="reference" href="#parameters" id="id35" name="id35">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></li>
<li><a class="reference" href="#optional-required" id="id36" name="id36">4.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></li>
<li><a class="reference" href="#class-templates" id="id39" name="id39">4&nbsp;&nbsp;&nbsp;Class Templates</a><ul class="auto-toc">
<li><a class="reference" href="#id7" id="id40" name="id40">4.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">keyword</span></tt></a></li>
<li><a class="reference" href="#parameters" id="id41" name="id41">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></li>
<li><a class="reference" href="#optional-required" id="id42" name="id42">4.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></li>
<li><a class="reference" href="#deduced" id="id43" name="id43">4.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">deduced</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#metafunctions" id="id37" name="id37">5&nbsp;&nbsp;&nbsp;Metafunctions</a><ul class="auto-toc">
<li><a class="reference" href="#binding" id="id38" name="id38">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></li>
<li><a class="reference" href="#lazy-binding" id="id39" name="id39">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></li>
<li><a class="reference" href="#metafunctions" id="id44" name="id44">5&nbsp;&nbsp;&nbsp;Metafunctions</a><ul class="auto-toc">
<li><a class="reference" href="#binding" id="id45" name="id45">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></li>
<li><a class="reference" href="#lazy-binding" id="id46" name="id46">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></li>
<li><a class="reference" href="#value-type" id="id47" name="id47">5.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">value_type</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#code-generation-macros" id="id40" name="id40">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-fun-r-n-l-h-p" id="id41" name="id41">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-keyword-n-k" id="id42" name="id42">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-match-p-a-x" id="id43" name="id43">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></li>
<li><a class="reference" href="#code-generation-macros" id="id48" name="id48">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-function-result-name-tag-namespace-arguments" id="id49" name="id49">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-member-function-result-name-tag-namespace-arguments" id="id50" name="id50">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MEMBER_FUNCTION(result,name,tag_namespace,arguments)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-constructor-cls-impl-tag-namespace-arguments" id="id51" name="id51">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_CONSTRUCTOR(cls,</span> <span class="pre">impl,</span> <span class="pre">tag_namespace,</span> <span class="pre">arguments)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-name-name" id="id52" name="id52">6.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_NAME(name)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-template-keyword-name" id="id53" name="id53">6.5&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_TEMPLATE_KEYWORD(name)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-fun-r-n-l-h-p" id="id54" name="id54">6.6&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-keyword-n-k" id="id55" name="id55">6.7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-match-p-a-x" id="id56" name="id56">6.8&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#configuration-macros" id="id44" name="id44">7&nbsp;&nbsp;&nbsp;Configuration Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-max-arity" id="id45" name="id45">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></li>
<li><a class="reference" href="#configuration-macros" id="id57" name="id57">7&nbsp;&nbsp;&nbsp;Configuration Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-max-arity" id="id58" name="id58">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#tutorial" id="id46" name="id46">8&nbsp;&nbsp;&nbsp;Tutorial</a></li>
<li><a class="reference" href="#tutorial" id="id59" name="id59">8&nbsp;&nbsp;&nbsp;Tutorial</a></li>
</ul>
</div>
<hr class="docutils" />
<div class="section" id="preliminaries">
<h1><a class="toc-backref" href="#id24" name="preliminaries">1&nbsp;&nbsp;&nbsp;Preliminaries</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id30" id="preliminaries" name="preliminaries">1&nbsp;&nbsp;&nbsp;Preliminaries</a></h1>
<p>This section covers some basic information you'll need to know in
order to understand this reference</p>
<div class="section" id="namespaces">
<h2><a class="toc-backref" href="#id25" name="namespaces">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id31" id="namespaces" name="namespaces">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></h2>
<p>In this document, all unqualified identifiers should be assumed to
be defined in namespace <tt class="docutils literal"><span class="pre">boost::parameter</span></tt> unless otherwise
specified.</p>
</div>
<div class="section" id="exceptions">
<h2><a class="toc-backref" href="#id26" name="exceptions">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id32" id="exceptions" name="exceptions">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></h2>
<p>No operation described in this document
throws an exception unless otherwise specified.</p>
</div>
<div class="section" id="thread-safety">
<h2><a class="toc-backref" href="#id27" name="thread-safety">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id33" id="thread-safety" name="thread-safety">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></h2>
<p>All components of this library can be used safely from multiple
threads without synchronization.<a class="footnote-reference" href="#thread" id="id2" name="id2"><sup>1</sup></a></p>
</div>
<div class="section" id="typography">
<h2><a class="toc-backref" href="#id28" name="typography">1.4&nbsp;&nbsp;&nbsp;Typography</a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id34" id="typography" name="typography">1.4&nbsp;&nbsp;&nbsp;Typography</a></h2>
<p>Names written in <span class="concept">sans serif type</span> represent <a class="reference" href="../../../../more/generic_programming.html#concept">concepts</a>.</p>
<p>In code blocks, <em>italic type</em> represents unspecified text that
satisfies the requirements given in the detailed description that
@@ -105,9 +117,9 @@ argument in the result.</p>
</div>
</div>
<hr class="docutils" />
<div class="section" id="terminology">
<h1><a class="toc-backref" href="#id29" name="terminology">2&nbsp;&nbsp;&nbsp;Terminology</a></h1>
<span class="target" id="kw"></span><dl class="docutils">
<div class="section">
<h1><a class="toc-backref" href="#id35" id="terminology" name="terminology">2&nbsp;&nbsp;&nbsp;Terminology</a></h1>
<dl class="docutils" id="kw">
<dt>keyword</dt>
<dd>The name of a function parameter.</dd>
</dl>
@@ -140,12 +152,12 @@ reference whose <em>value</em> is <tt class="docutils literal"><span class="pre"
</dd>
</dl>
<span class="target" id="tagged-default"></span><dl class="docutils">
<dt>tagged default </dt>
<dt>tagged default</dt>
<dd>A <a class="reference" href="#tagged-reference">tagged reference</a> whose <em>value</em> represents the value of a
default argument.</dd>
</dl>
<span class="target" id="tagged-lazy-default"></span><dl class="docutils">
<dt>tagged lazy default </dt>
<dt>tagged lazy default</dt>
<dd>A <a class="reference" href="#tagged-reference">tagged reference</a> whose <em>value</em>, when invoked with no
arguments, computes a default argument value.</dd>
</dl>
@@ -164,16 +176,16 @@ models <a class="reference" href="#argumentpack"><span class="concept">ArgumentP
</div>
</div>
<hr class="docutils" />
<div class="section" id="concepts">
<h1><a class="toc-backref" href="#id30" name="concepts">3&nbsp;&nbsp;&nbsp;Concepts</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id36" id="concepts" name="concepts">3&nbsp;&nbsp;&nbsp;Concepts</a></h1>
<p>This section describes the generic type <a class="reference" href="../../../../more/generic_programming.html#concept">concepts</a> used by the Parameter library.</p>
<div class="section" id="argumentpack">
<h2><a class="toc-backref" href="#id31" name="argumentpack">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id37" id="argumentpack" name="argumentpack">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></h2>
<p>An <span class="concept">ArgumentPack</span> is a collection of <a class="reference" href="#tagged-reference">tagged reference</a>s to the
actual arguments passed to a function. Every <span class="concept">ArgumentPack</span> is
also a valid MPL <a class="reference" href="../../../mpl/doc/refmanual/forward-sequence.html"><span class="concept">Forward Sequence</span></a> consisting of the <a class="reference" href="#keyword-tag-type">keyword tag type</a>s in its <a class="reference" href="#tagged-reference">tagged reference</a>s.</p>
<div class="section" id="requirements">
<h3><a name="requirements">Requirements</a></h3>
<div class="section">
<h3><a id="requirements" name="requirements">Requirements</a></h3>
<p>In the table below,</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <span class="concept">ArgumentPack</span></li>
@@ -194,10 +206,10 @@ will be propagated to the caller.</p>
<col width="40%" />
</colgroup>
<thead valign="bottom">
<tr><th>Expression</th>
<th>Type</th>
<th>Requirements</th>
<th>Semantics/Notes</th>
<tr><th class="head">Expression</th>
<th class="head">Type</th>
<th class="head">Requirements</th>
<th class="head">Semantics/Notes</th>
</tr>
</thead>
<tbody valign="top">
@@ -236,14 +248,14 @@ all the elements of both <tt class="docutils literal"><span class="pre">x</span>
</table>
</div>
</div>
<div class="section" id="id5">
<h2><a class="toc-backref" href="#id32" name="id5">3.2&nbsp;&nbsp;&nbsp;<span class="target" id="parameterspec"></span><span class="concept">ParameterSpec</span></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id38" id="id5" name="id5"><span id="parameterspec"></span>3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></h2>
<p>A <span class="concept">ParameterSpec</span> describes the type requirements for arguments
corresponding to a given <a class="reference" href="#kw">keyword</a> 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,</p>
<span class="target" id="conditions"></span><ul class="simple">
<ul class="simple" id="conditions">
<li><tt class="docutils literal"><span class="pre">K</span></tt> is the <span class="concept">ParameterSpec</span>'s <a class="reference" href="#keyword-tag-type">keyword tag type</a></li>
<li><tt class="docutils literal"><span class="pre">A</span></tt> is an <a class="reference" href="#intended-argument-type">intended argument type</a> associated with <tt class="docutils literal"><span class="pre">K</span></tt>, if any</li>
<li><tt class="docutils literal"><span class="pre">F</span></tt> is a unary <a class="reference" href="../../../mpl/doc/refmanual/lambda-expression.html">MPL lambda expression</a></li>
@@ -256,13 +268,13 @@ argument type. In each row,</p>
<col width="47%" />
</colgroup>
<thead valign="bottom">
<tr><th>Type</th>
<th><tt class="docutils literal"><span class="pre">A</span></tt> required</th>
<th>Condition <tt class="docutils literal"><span class="pre">A</span></tt> must satisfy</th>
<tr><th class="head">Type</th>
<th class="head"><tt class="docutils literal"><span class="pre">A</span></tt> required</th>
<th class="head">Condition <tt class="docutils literal"><span class="pre">A</span></tt> must satisfy</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a><tt class="docutils literal"><span class="pre">&lt;K&gt;</span></tt></td>
<tr><td><tt class="docutils literal"><span class="pre">K</span></tt></td>
<td>no</td>
<td><em>n/a</em></td>
</tr>
@@ -283,10 +295,10 @@ arguments that will be matched by <a class="reference" href="index.html#forwardi
</div>
</div>
<hr class="docutils" />
<div class="section" id="class-templates">
<h1><a class="toc-backref" href="#id33" name="class-templates">4&nbsp;&nbsp;&nbsp;Class Templates</a></h1>
<div class="section" id="id7">
<h2><a class="toc-backref" href="#id34" name="id7">4.1&nbsp;&nbsp;&nbsp;<span class="target" id="keyword"></span><tt class="docutils literal"><span class="pre">keyword</span></tt></a></h2>
<div class="section">
<h1><a class="toc-backref" href="#id39" id="class-templates" name="class-templates">4&nbsp;&nbsp;&nbsp;Class Templates</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id40" id="id7" name="id7"><span id="keyword"></span>4.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">keyword</span></tt></a></h2>
<p>The type of every <a class="reference" href="#keyword-object">keyword object</a> is a specialization of <tt class="docutils literal"><span class="pre">keyword</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@@ -311,7 +323,7 @@ struct keyword
static keyword&lt;Tag&gt;&amp; <a class="reference" href="#get">get</a>();
};
</pre>
<span class="target" id="operator"></span><dl class="docutils">
<dl class="docutils" id="operator">
<dt><tt class="docutils literal"><span class="pre">operator=</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> operator=(T&amp; value) const;
@@ -330,7 +342,7 @@ template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="
</table>
</dd>
</dl>
<span class="target" id="id9"></span><dl class="docutils">
<dl class="docutils" id="id9">
<dt><tt class="docutils literal"><span class="pre">operator|</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class T&gt; <em>tagged default</em> operator|(T&amp; x) const;
@@ -346,7 +358,7 @@ template &lt;class T&gt; <em>tagged default</em> operator|(T const&amp; x) const
</table>
</dd>
</dl>
<span class="target" id="id10"></span><dl class="docutils">
<dl class="docutils" id="id10">
<dt><tt class="docutils literal"><span class="pre">operator||</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class F&gt; <em>tagged lazy default</em> operator||(F const&amp; g) const;
@@ -363,7 +375,7 @@ template &lt;class F&gt; <em>tagged lazy default</em> operator||(F const&amp; g)
</table>
</dd>
</dl>
<span class="target" id="get"></span><dl class="docutils">
<dl class="docutils" id="get">
<dt><tt class="docutils literal"><span class="pre">get</span></tt></dt>
<dd><pre class="first literal-block">
static keyword&lt;Tag&gt;&amp; get();
@@ -383,8 +395,8 @@ simultaneously.</td>
</dd>
</dl>
</div>
<div class="section" id="parameters">
<h2><a class="toc-backref" href="#id35" name="parameters">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id41" id="parameters" name="parameters">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></h2>
<p>Provides an interface for assembling the actual arguments to a
<cite>forwarding function</cite> into an <span class="concept">ArgumentPack</span>, in which any
<a class="reference" href="#positional">positional</a> arguments will be tagged according to the
@@ -408,13 +420,15 @@ struct parameters
};
template &lt;class A0&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0) const;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0&amp; a0) const;
template &lt;class A0, class A1&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, A1 const&amp; a1) const;
<span class="doublesize"></span>
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0&amp; a0, A1&amp; a1) const;
<span class="vellipsis"></span>
template &lt;class A0, class A1, …class Aβ&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, A1 const&amp; a1, …Aβ const&amp; aβ) const;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0&amp; a0, A1&amp; a1, …Aβ&amp; aβ) const;
};
</pre>
<table class="docutils field-list" frame="void" rules="none">
@@ -431,15 +445,28 @@ struct parameters
follows, for any argument type <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em>:</p>
<blockquote class="last">
<div class="line-block">
<div class="line">let <tt class="docutils literal"><span class="pre">D0</span></tt> the set [d0, …, d<em>j</em>] of all <strong>deduced</strong> <em>parameter specs</em> in [<tt class="docutils literal"><span class="pre">P0</span></tt>, …, <tt class="docutils literal"><span class="pre">P</span></tt>β]</div>
<div class="line"><tt class="docutils literal"><span class="pre">R</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em>'s <a class="reference" href="#intended-argument-type">intended argument type</a></div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">if <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em> is a result type of <tt class="docutils literal"><span class="pre">keyword&lt;T&gt;::</span></tt><a class="reference" href="#operator"><tt class="docutils literal"><span class="pre">operator=</span></tt></a></div>
<div class="line">then </div>
<div class="line">then</div>
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">T</span></tt></div>
</div>
<div class="line">else </div>
<div class="line">else</div>
<div class="line-block">
<div class="line">if some <tt class="docutils literal"><span class="pre">A</span></tt><em>j</em> where <em>j</em><em>i</em> is a result type of <tt class="docutils literal"><span class="pre">keyword&lt;T&gt;::</span></tt><a class="reference" href="#operator"><tt class="docutils literal"><span class="pre">operator=</span></tt></a></div>
<div class="line"><em>or</em> some <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> in <em>j</em><em>i</em> is <strong>deduced</strong></div>
<div class="line">then</div>
<div class="line-block">
<div class="line">if some <em>parameter spec</em> <tt class="docutils literal"><span class="pre">d</span></tt><em>j</em> in <tt class="docutils literal"><span class="pre">D</span></tt><em>i</em> matches <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em></div>
<div class="line">then</div>
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">d</span></tt><em>j</em>'s <a class="reference" href="#keyword-tag-type">keyword tag type</a>.</div>
<div class="line"><tt class="docutils literal"><span class="pre">D</span></tt><sub>i+1</sub> is <tt class="docutils literal"><span class="pre">D</span></tt><em>i</em> - [<tt class="docutils literal"><span class="pre">d</span></tt><em>j</em>]</div>
</div>
</div>
<div class="line">else</div>
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">P</span></tt><em>i</em>'s <a class="reference" href="#keyword-tag-type">keyword tag type</a>.</div>
</div>
@@ -447,7 +474,7 @@ follows, for any argument type <tt class="docutils literal"><span class="pre">A<
</div>
</blockquote>
</div>
<span class="target" id="match"></span><dl class="docutils">
<dl class="docutils" id="match">
<dt><tt class="docutils literal"><span class="pre">match</span></tt></dt>
<dd><p class="first">A <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> used to remove a <a class="reference" href="index.html#forwarding-functions">forwarding function</a> from overload resolution.</p>
<table class="docutils field-list" frame="void" rules="none">
@@ -464,7 +491,7 @@ below), then <tt class="docutils literal"><span class="pre">parameters&lt;P0,P1,
every <em>j</em> in 0…β, either:</p>
<ul class="last simple">
<li><tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is the <em>unspecified</em> default</li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is a specialization of <a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a>,</li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is a <em>keyword tag type</em></li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is <a class="reference" href="#optional"><tt class="docutils literal"><span class="pre">optional</span></tt></a> <tt class="docutils literal"><span class="pre">&lt;X,F&gt;</span></tt> and either<ul>
<li><tt class="docutils literal"><span class="pre">X</span></tt> is not <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> for any <em>i</em>,</li>
<li><strong>or</strong> <tt class="docutils literal"><span class="pre">X</span></tt> is some <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> and <tt class="docutils literal"><span class="pre">mpl::apply&lt;F,R</span></tt><em>i</em><tt class="docutils literal"><span class="pre">&gt;::type::value</span></tt> is <tt class="docutils literal"><span class="pre">true</span></tt></li>
@@ -478,11 +505,13 @@ every <em>j</em> in 0…β, either:</p>
</ul>
</dd>
</dl>
<span class="target" id="id13"></span><dl class="docutils">
<dl class="docutils" id="id13">
<dt><tt class="docutils literal"><span class="pre">operator()</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class A0&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> operator()(A0 const&amp; a0) const;
<span class="doublesize"></span>
<span class="vellipsis"></span>
template &lt;class A0, …class Aβ&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, …Aβ const&amp; aβ) const;
</pre>
<table class="last docutils field-list" frame="void" rules="none">
@@ -501,8 +530,8 @@ template &lt;class A0, …class Aβ&gt; <a class="reference" href="#argumentpack
</dd>
</dl>
</div>
<div class="section" id="optional-required">
<h2><a class="toc-backref" href="#id36" name="optional-required">4.3&nbsp;&nbsp;&nbsp;<span class="target" id="required"></span><span class="target" id="optional"></span><tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id42" id="optional-required" name="optional-required"><span id="required"></span><span id="optional"></span>4.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></h2>
<p>These templates describe the requirements on a function parameter.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@@ -531,14 +560,31 @@ struct required;
<p>The default value of <tt class="docutils literal"><span class="pre">Predicate</span></tt> is an unspecified <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> that returns
<tt class="docutils literal"><span class="pre">mpl::true_</span></tt> for any argument.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id43" id="deduced" name="deduced">4.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">deduced</span></tt></a></h2>
<p>This template is used to wrap the <em>keyword tag</em> argument to
<tt class="docutils literal"><span class="pre">optional</span></tt> or <tt class="docutils literal"><span class="pre">required</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/parameters.hpp">boost/parameter/parameters.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class Tag&gt;
struct deduced;
</pre>
</div>
</div>
<hr class="docutils" />
<div class="section" id="metafunctions">
<h1><a class="toc-backref" href="#id37" name="metafunctions">5&nbsp;&nbsp;&nbsp;Metafunctions</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id44" id="metafunctions" name="metafunctions">5&nbsp;&nbsp;&nbsp;Metafunctions</a></h1>
<p>A <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> is conceptually a function that operates on, and
returns, C++ types.</p>
<div class="section" id="binding">
<h2><a class="toc-backref" href="#id38" name="binding">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id45" id="binding" name="binding">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></h2>
<p>Returns the result type of indexing an argument pack with a
<a class="reference" href="#keyword-tag-type">keyword tag type</a> or with a <a class="reference" href="#tagged-default">tagged default</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
@@ -568,8 +614,8 @@ having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt cl
</tbody>
</table>
</div>
<div class="section" id="lazy-binding">
<h2><a class="toc-backref" href="#id39" name="lazy-binding">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id46" id="lazy-binding" name="lazy-binding">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></h2>
<p>Returns the result type of indexing an argument pack with a <a class="reference" href="#tagged-lazy-default">tagged lazy default</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@@ -593,19 +639,324 @@ struct lazy_binding
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the reference type of the <a class="reference" href="#tagged-reference">tagged reference</a> in <tt class="docutils literal"><span class="pre">A</span></tt>
having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt class="docutils literal"><span class="pre">K</span></tt>, if any. If no such <a class="reference" href="#tagged-reference">tagged reference</a> exists, returns <tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt>.<a class="footnote-reference" href="#no-result-of" id="id17" name="id17"><sup>2</sup></a></td>
having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt class="docutils literal"><span class="pre">K</span></tt>, if any. If no such <a class="reference" href="#tagged-reference">tagged reference</a> exists, returns <tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt>.<a class="footnote-reference" href="#no-result-of" id="id18" name="id18"><sup>2</sup></a></td>
</tr>
</tbody>
</table>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id47" id="value-type" name="value-type">5.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">value_type</span></tt></a></h2>
<p>Returns the result type of indexing an argument pack with a
<a class="reference" href="#keyword-tag-type">keyword tag type</a> or with a <a class="reference" href="#tagged-default">tagged default</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined n:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/value_type.hpp">boost/parameter/value_type.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class A, class K, class D = void&gt;
struct value_type
{
typedef … type;
};
</pre>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a>.</p>
</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">the type of the <a class="reference" href="#tagged-reference">tagged reference</a> in <tt class="docutils literal"><span class="pre">A</span></tt>
having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt class="docutils literal"><span class="pre">K</span></tt>, if any. If no such <a class="reference" href="#tagged-reference">tagged reference</a> exists, returns <tt class="docutils literal"><span class="pre">D</span></tt>. Equivalent to:</p>
<pre class="literal-block">
typename remove_reference&lt;
typename binding&lt;A, K, D&gt;::type
&gt;::type
</pre>
<p class="last">… when <tt class="docutils literal"><span class="pre">D</span></tt> is not a reference type.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="docutils" />
<div class="section" id="code-generation-macros">
<h1><a class="toc-backref" href="#id40" name="code-generation-macros">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id48" id="code-generation-macros" name="code-generation-macros">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a></h1>
<p>Macros in this section can be used to ease the writing of code
using the Parameter libray by eliminating repetitive boilerplate.</p>
<div class="section" id="boost-parameter-fun-r-n-l-h-p">
<h2><a class="toc-backref" href="#id41" name="boost-parameter-fun-r-n-l-h-p">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id49" id="boost-parameter-function-result-name-tag-namespace-arguments" name="boost-parameter-function-result-name-tag-namespace-arguments">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)</span></tt></a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/preprocessor.hpp">boost/parameter/preprocessor.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">result</span></tt> is the parenthesized return type of the function.
<tt class="docutils literal"><span class="pre">name</span></tt> is the base name of the function, this is the name of the
generated forwarding functions. <tt class="docutils literal"><span class="pre">tag_namespace</span></tt> is the namespace in
which the keywords used by the function resides. <tt class="docutils literal"><span class="pre">arguments</span></tt> is
a list of <em>argument specifiers</em>, as defined below.</p>
</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">Argument specifiers syntax:</th></tr>
<tr><td>&nbsp;</td><td class="field-body"><pre class="first literal-block">
argument-specifiers ::= <em>specifier-group</em> {<em>specifier-group</em>}
specifier-group0 ::= <em>specifier-group1</em> |
( '<strong>(</strong>' '<strong>deduced</strong>' <em>specifier-group1</em> {<em>specifier-group1</em>} '<strong>)</strong>' )
specifier-group1 ::= ( '<strong>(</strong>' '<strong>optional</strong>' <em>optional-specifier</em> {<em>optional-specifier</em>} '<strong>)</strong>' ) |
( '<strong>(</strong>' '<strong>required</strong>' <em>required-specifier</em> {<em>required-specifier</em>} '<strong>)</strong>' )
optional-specifier ::= '<strong>(</strong>' <em>name</em> '<strong>,</strong>' <em>restriction</em> '<strong>,</strong>' <em>default-value</em> ')'
required-specifier ::= '<strong>(</strong>' <em>name</em> '<strong>,</strong>' <em>restriction</em> ')'
restriction ::= ('<strong>*</strong>' '<strong>(</strong>' <em>lambda-expression</em> '<strong>)</strong>' ) |
( '<strong>(</strong>' <em>typename</em> '<strong>)</strong>' ) |
'<strong>*</strong>'
</pre>
<p class="last"><tt class="docutils literal"><span class="pre">name</span></tt> is any valid C++ identifier. <tt class="docutils literal"><span class="pre">default-value</span></tt> is any valid
C++ expression. <tt class="docutils literal"><span class="pre">typename</span></tt> is the name of a type.
<tt class="docutils literal"><span class="pre">lambda-expression</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/lambda-expression.html">MPL lambda expression</a>.</p>
</td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name" colspan="2">Generated names in enclosing scope:</th></tr>
<tr><td>&nbsp;</td><td class="field-body"><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">boost_param_result_</span> <span class="pre">##</span> <span class="pre">__LINE__</span> <span class="pre">##</span> <span class="pre">name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">boost_param_params_</span> <span class="pre">##</span> <span class="pre">__LINE__</span> <span class="pre">##</span> <span class="pre">name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">boost_param_parameters_</span> <span class="pre">##</span> <span class="pre">__LINE__</span> <span class="pre">##</span> <span class="pre">name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">boost_param_impl</span> <span class="pre">##</span> <span class="pre">name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">boost_param_default_</span> <span class="pre">##</span> <span class="pre">__LINE__</span> <span class="pre">##</span> <span class="pre">name</span></tt></li>
</ul>
</td>
</tr>
</tbody>
</table>
<dl class="docutils">
<dt>Approximate expansion:</dt>
<dd><p class="first"><strong>Where</strong>:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">n</span></tt> denotes the <em>minimum</em> arity, as determined from <tt class="docutils literal"><span class="pre">arguments</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">m</span></tt> denotes the <em>maximum</em> arity, as determined from <tt class="docutils literal"><span class="pre">arguments</span></tt>.</li>
</ul>
<pre class="last literal-block">
template &lt;class T&gt;
struct boost_param_result_ ## __LINE__ ## <strong>name</strong>
{
typedef <strong>result</strong> type;
};
struct boost_param_params_ ## __LINE__ ## <strong>name</strong>
: boost::parameter::parameters&lt;
<em>list of parameter specifications, based on arguments</em>
&gt;
{};
typedef boost_param_params_ ## __LINE__ ## <strong>name</strong>
boost_param_parameters_ ## __LINE__ ## <strong>name</strong>;
template &lt;class A0, …, class A<strong>n</strong>&gt;
<em>result type</em> <strong>name</strong>(
A0 <em>cv</em>&amp; a0, …, A<strong>n</strong> <em>cv</em>&amp; a<strong>n</strong>
, typename boost_param_parameters_ ## __LINE__ ## <strong>name</strong>::match&lt;
A0 <em>cv</em>, …, A<strong>n</strong> <em>cv</em>
&gt;::type = boost_param_parameters_ ## __LINE__ ## <strong>name</strong>()
)
{
<em>… forward to implementation …</em>
}
<span class="vellipsis"></span>
template &lt;class A0, …, class A<strong>m</strong>&gt;
<em>result type</em> <strong>name</strong>(
A0 <em>cv</em>&amp; a0, …, A<strong>m</strong> <em>cv</em>&amp; a<strong>m</strong>
, typename boost_param_parameters_ ## __LINE__ ## <strong>name</strong>::match&lt;
A0 <em>cv</em>, …, A<strong>m</strong> <em>cv</em>
&gt;::type = boost_param_parameters_ ## __LINE__ ## <strong>name</strong>()
)
{
<em>… forward to implementation …</em>
}
template &lt;
class ResultType
, class <em>argument name</em><strong>0</strong> ## _type
, class <em>argument name</em><strong>m</strong> ## _type
&gt;
ResultType boost_param_default_ ## __LINE__ ## <strong>name</strong>(
(ResultType(*)())
, <em>argument name</em><strong>0</strong> ## _type&amp; <em>argument name</em><strong>0</strong>
, <em>argument name</em><strong>m</strong> ## _type&amp; <em>argument name</em><strong>m</strong>
)
</pre>
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id50" id="boost-parameter-member-function-result-name-tag-namespace-arguments" name="boost-parameter-member-function-result-name-tag-namespace-arguments">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MEMBER_FUNCTION(result,name,tag_namespace,arguments)</span></tt></a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/preprocessor.hpp">boost/parameter/preprocessor.hpp</a></td>
</tr>
</tbody>
</table>
<p>See <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)</span></tt></p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id51" id="boost-parameter-constructor-cls-impl-tag-namespace-arguments" name="boost-parameter-constructor-cls-impl-tag-namespace-arguments">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_CONSTRUCTOR(cls,</span> <span class="pre">impl,</span> <span class="pre">tag_namespace,</span> <span class="pre">arguments)</span></tt></a></h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/preprocessor.hpp">boost/parameter/preprocessor.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">cls</span></tt> is the name of this class. <tt class="docutils literal"><span class="pre">impl</span></tt> is the
parenthesized implementation base class for <tt class="docutils literal"><span class="pre">cls</span></tt>.
<tt class="docutils literal"><span class="pre">tag_namespace</span></tt> is the namespace in which the keywords
used by the function resides. <tt class="docutils literal"><span class="pre">arguments</span></tt> is
a list of <em>argument specifiers</em>, as defined in
<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)</span></tt>.</p>
</td>
</tr>
<tr class="field"><th class="field-name" colspan="2">Generated names in enclosing scope:</th></tr>
<tr><td>&nbsp;</td><td class="field-body"><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">boost_param_params_</span> <span class="pre">##</span> <span class="pre">__LINE__</span> <span class="pre">##</span> <span class="pre">ctor</span></tt></li>
<li><tt class="docutils literal"><span class="pre">constructor_parameters</span> <span class="pre">##</span> <span class="pre">__LINE__</span></tt></li>
</ul>
</td>
</tr>
</tbody>
</table>
<dl class="docutils">
<dt>Approximate expansion:</dt>
<dd><p class="first"><strong>Where</strong>:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">n</span></tt> denotes the <em>minimum</em> arity, as determined from <tt class="docutils literal"><span class="pre">arguments</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">m</span></tt> denotes the <em>maximum</em> arity, as determined from <tt class="docutils literal"><span class="pre">arguments</span></tt>.</li>
</ul>
<pre class="last literal-block">
struct boost_param_params_ ## __LINE__ ## ctor
: boost::parameter::parameters&lt;
<em>list of parameter specifications, based on arguments</em>
&gt;
{};
typedef boost_param_params_ ## __LINE__ ## <strong>name</strong>
constructor_parameters ## __LINE__;
template &lt;class A0, …, class A<strong>n</strong>&gt;
<em>cls</em>(A0 const&amp; a0, …, A<strong>n</strong> const&amp; a<strong>n</strong>)
: <em>impl</em>(constructor_parameters ## __LINE__(a0, …, a<strong>n</strong>))
{}
<span class="vellipsis"></span>
template &lt;class A0, …, class A<strong>m</strong>&gt;
<em>cls</em>(A0 const&amp; a0, …, A<strong>n</strong> const&amp; a<strong>m</strong>)
: <em>impl</em>(constructor_parameters ## __LINE__(a0, …, a<strong>m</strong>))
{}
</pre>
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id52" id="boost-parameter-name-name" name="boost-parameter-name-name">6.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_NAME(name)</span></tt></a></h2>
<p>Declares a tag-type and keyword object.</p>
<p>Expands to:</p>
<p><strong>If</strong> <em>name</em> is of the form:</p>
<pre class="literal-block">
(<em>tag-name</em>, <em>namespace-name</em>) <em>object-name</em>
</pre>
<p><strong>then</strong></p>
<pre class="literal-block">
namespace <em>namespace-name</em>
{
struct <em>tag-name</em>
{
static char const* keyword_name()
{
return ##<em>tag-name</em>;
}
typedef <em>implementation defined</em> _;
typedef <em>implementation defined</em> _1;
};
}
::boost::parameter::keyword&lt;<em>tag-namespace</em>::<em>tag-name</em>&gt; const&amp; <em>object-name</em>
= ::boost::parameter::keyword&lt;<em>tag-namespace</em>::<em>tag-name</em>&gt;::instance;
</pre>
<p><strong>Else</strong></p>
<pre class="literal-block">
namespace tag
{
struct <em>name</em>
{
static char const* keyword_name()
{
return ##<em>name</em>;
}
typedef <em>implementation defined</em> _;
typedef <em>implementation defined</em> _1;
};
}
::boost::parameter::keyword&lt;tag::<em>name</em>&gt; const&amp; _<em>name</em>
= ::boost::parameter::keyword&lt;tag::<em>name</em>&gt;::instance;
</pre>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id53" id="boost-parameter-template-keyword-name" name="boost-parameter-template-keyword-name">6.5&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_TEMPLATE_KEYWORD(name)</span></tt></a></h2>
<p>Expands to:</p>
<pre class="literal-block">
namespace tag
{
struct <em>name</em>;
}
template &lt;class T&gt;
struct <em>name</em>
: ::boost::parameter::template_keyword&lt;tag::<em>name</em>, T&gt;
{};
</pre>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id54" id="boost-parameter-fun-r-n-l-h-p" name="boost-parameter-fun-r-n-l-h-p">6.6&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></h2>
<div class="admonition-deprecated admonition">
<p class="first admonition-title">Deprecated</p>
<p class="last">This macro has been deprecated in favor of
<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUNCTION</span></tt>.</p>
</div>
<p>Generates a sequence of <a class="reference" href="index.html#forwarding-functions">forwarding function</a> templates named
<tt class="docutils literal"><span class="pre">n</span></tt>, with arities ranging from <tt class="docutils literal"><span class="pre">l</span></tt> to <tt class="docutils literal"><span class="pre">h</span></tt> , returning <tt class="docutils literal"><span class="pre">r</span></tt>,
and using <tt class="docutils literal"><span class="pre">p</span></tt> to control overload resolution and assign tags to
@@ -646,7 +997,9 @@ r name(
{
return <strong>name</strong>_with_named_params(<strong>p</strong>(x1,x2,…x<strong>l</strong>,x##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)));
}
<span class="doublesize"></span>
<span class="vellipsis"></span>
template &lt;class A1, class A2, …class A<strong>h</strong>&gt;
r name(
A1 const&amp; a1, A2 const&amp; a2, …A<strong>h</strong> const&amp; x<strong>h</strong>
@@ -658,8 +1011,13 @@ r name(
</dd>
</dl>
</div>
<div class="section" id="boost-parameter-keyword-n-k">
<h2><a class="toc-backref" href="#id42" name="boost-parameter-keyword-n-k">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id55" id="boost-parameter-keyword-n-k" name="boost-parameter-keyword-n-k">6.7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></h2>
<div class="admonition-deprecated admonition">
<p class="first admonition-title">Deprecated</p>
<p class="last">This macro has been deprecated in favor of
<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_NAME</span></tt>.</p>
</div>
<p>Generates the declaration of a <a class="reference" href="#keyword-tag-type">keyword tag type</a> named <tt class="docutils literal"><span class="pre">k</span></tt> in
namespace <tt class="docutils literal"><span class="pre">n</span></tt>, and a corresponding <a class="reference" href="#keyword-object">keyword object</a> definition in
the enclosing namespace.</p>
@@ -675,7 +1033,7 @@ the enclosing namespace.</p>
<dt>Generates</dt>
<dd><pre class="first last literal-block">
namespace <strong>n</strong> { struct <strong>k</strong>; }
namespace {
namespace {
boost::parameter::keyword&lt;<em>tag-namespace</em>::<strong>k</strong>&gt;&amp; <strong>k</strong>
= boost::parameter::keyword&lt;<em>tag-namespace</em>::<strong>k</strong>&gt;::get();
}
@@ -683,8 +1041,8 @@ namespace {
</dd>
</dl>
</div>
<div class="section" id="boost-parameter-match-p-a-x">
<h2><a class="toc-backref" href="#id43" name="boost-parameter-match-p-a-x">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></h2>
<div class="section">
<h2><a class="toc-backref" href="#id56" id="boost-parameter-match-p-a-x" name="boost-parameter-match-p-a-x">6.8&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></h2>
<p>Generates a defaulted parameter declaration for a <a class="reference" href="index.html#forwarding-functions">forwarding
function</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
@@ -699,7 +1057,7 @@ function</a>.</p>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">a</span></tt> is a <a class="reference" href="http://www.boost.org/libs/preprocessor/doc/data.html">Boost.Preprocessor sequence</a>
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">a</span></tt> is a <a class="reference" href="http://www.boost.org/libs/preprocessor/doc/data.html">Boost.Preprocessor sequence</a>
of the form</p>
<pre class="last literal-block">
(A0)(A1)…(A<em>n</em>)
@@ -717,10 +1075,10 @@ typename <strong>p</strong>::match&lt;<strong>A0</strong>,<strong>A1</strong>…
</dl>
</div>
</div>
<div class="section" id="configuration-macros">
<h1><a class="toc-backref" href="#id44" name="configuration-macros">7&nbsp;&nbsp;&nbsp;Configuration Macros</a></h1>
<div class="section" id="boost-parameter-max-arity">
<h2><a class="toc-backref" href="#id45" name="boost-parameter-max-arity">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></h2>
<div class="section">
<h1><a class="toc-backref" href="#id57" id="configuration-macros" name="configuration-macros">7&nbsp;&nbsp;&nbsp;Configuration Macros</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id58" id="boost-parameter-max-arity" name="boost-parameter-max-arity">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></h2>
<p>Determines the maximum number of arguments supported by the
library. Will only be <tt class="docutils literal"><span class="pre">#defined</span></tt> by the library if it is not
already <tt class="docutils literal"><span class="pre">#defined</span></tt>.</p>
@@ -742,8 +1100,8 @@ already <tt class="docutils literal"><span class="pre">#defined</span></tt>.</p>
</table>
</div>
</div>
<div class="section" id="tutorial">
<h1><a class="toc-backref" href="#id46" name="tutorial">8&nbsp;&nbsp;&nbsp;Tutorial</a></h1>
<div class="section">
<h1><a class="toc-backref" href="#id59" id="tutorial" name="tutorial">8&nbsp;&nbsp;&nbsp;Tutorial</a></h1>
<p>Follow <a class="reference" href="index.html#tutorial">this link</a> to the Boost.Parameter tutorial
documentation.</p>
<hr class="docutils" />
@@ -761,17 +1119,18 @@ where it could make a difference.</td></tr>
<table class="docutils footnote" frame="void" id="no-result-of" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="no-result-of">[2]</a></td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id17">2</a>)</em> Where <a class="reference" href="../../../utility/utility.htm#BOOST_NO_RESULT_OF"><tt class="docutils literal"><span class="pre">BOOST_NO_RESULT_OF</span></tt></a> is <tt class="docutils literal"><span class="pre">#defined</span></tt>,
<tr><td class="label"><a name="no-result-of">[2]</a></td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id18">2</a>)</em> Where <a class="reference" href="../../../utility/utility.htm#BOOST_NO_RESULT_OF"><tt class="docutils literal"><span class="pre">BOOST_NO_RESULT_OF</span></tt></a> is <tt class="docutils literal"><span class="pre">#defined</span></tt>,
<tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt> is replaced by
<tt class="docutils literal"><span class="pre">F::result_type</span></tt>.</td></tr>
</tbody>
</table>
</div>
</div>
<hr class="docutils footer" />
<div class="footer">
Generated on: 2006-01-27 01:56 UTC.
<hr class="footer" />
Generated on: 2007-05-03 14:17 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -1,3 +1,8 @@
/* Copyright David Abrahams 2006. 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)
*/
@import "../../../../rst.css";
div.section div.section div.section dl {
@@ -14,8 +19,12 @@ img {
}
span.vellipsis {
line-height: 30% ;
font-size: 200% ;
display: block;
width: 5px;
height: 22px;
background: url("vellipsis.gif");
margin-left: 3em;
text-indent: -1000px;
}

BIN
doc/html/vellipsis.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 B

File diff suppressed because it is too large Load Diff

771
doc/python.rst Executable file
View File

@@ -0,0 +1,771 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The Boost Parameter Library Python Binding Documentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
:Authors: Daniel Wallin
:Contact: dalwan01@student.umu.se
:organization: `Boost Consulting`_
:date: $Date$
:copyright: Copyright David Abrahams, Daniel Wallin
2005. Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at http://www.boost.org/LICENSE_1_0.txt)
:abstract: Makes it possible to bind Boost.Parameter-enabled
functions, operators and constructors to Python.
|(logo)|__
.. |(logo)| image:: ../../../../boost.png
:alt: Boost
__ ../../../../index.htm
.. _`Boost Consulting`: http://www.boost-consulting.com
.. role:: class
:class: class
.. role:: concept
:class: concept
.. role:: function
:class: function
.. |ParameterSpec| replace:: :concept:`ParameterSpec`
.. contents::
:depth: 1
Introduction
------------
``boost/parameter/python.hpp`` introduces a group of |def_visitors|_ that can
be used to easily expose Boost.Parameter-enabled member functions to Python with
Boost.Python. It also provides a function template ``def()`` that can be used
to expose Boost.Parameter-enabled free functions.
.. |def_visitor| replace:: ``def_visitor``
.. |def_visitors| replace:: ``def_visitors``
.. _def_visitor: def_visitors_
.. _def_visitors: ../../../python/doc/v2/def_visitor.html
When binding a Boost.Parameter enabled function, the keyword tags
must be specified. Additionally, because Boost.Parameter enabled
functions are templates, the desired function signature must be
specified.
.. The keyword tags are specified as an `MPL Sequence`_, using the
pointer qualifications described in |ParameterSpec|_ below. The
signature is also specifid as an `MPL sequence`_ of parameter
types. Additionally, ``boost::parameter::python::function`` and
``boost::parameter::python::def`` requires a class with forwarding
overloads. We will take a closer look at how this is done in the
tutorial section below.
The keyword tags and associated argument types are specified as an `MPL
Sequence`_, using the function type syntax described in |ParameterSpec|_
below. Additionally, ``boost::parameter::python::function`` and
``boost::parameter::python::def`` requires a class with forwarding overloads.
We will take a closer look at how this is done in the tutorial section below.
.. The last two sentences are terribly vague. Which namespace is
.. ``function`` in? Isn't the return type always needed? What
.. else are we going to do other than pass these sequences to
.. function?
.. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html
.. _parameterspec: `concept ParameterSpec`_
Tutorial
--------
In this section we will outline the steps needed to bind a simple
Boost.Parameter-enabled member function to Python. Knowledge of the
Boost.Parameter macros_ are required to understand this section.
.. _macros: index.html
The class and member function we are interested in binding looks
like this:
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
// First the keywords
BOOST_PARAMETER_KEYWORD(tag, title)
BOOST_PARAMETER_KEYWORD(tag, width)
BOOST_PARAMETER_KEYWORD(tag, height)
class window
{
public:
BOOST_PARAMETER_MEMBER_FUNCTION(
(void), open, tag,
(required (title, (std::string)))
(optional (width, (unsigned), 400)
(height, (unsigned), 400))
)
{
*… function implementation …*
}
};
.. @example.prepend('#include <cassert>')
.. @example.replace_emphasis('''
assert(title == "foo");
assert(height == 20);
assert(width == 400);
''')
It defines a set of overloaded member functions called ``open`` with one
required parameter and two optional ones. To bind this member function to
Python we use the binding utility ``boost::parameter::python::function``.
``boost::parameter::python::function`` is a |def_visitor|_ that we'll instantiate
and pass to ``boost::python::class_::def()``.
To use ``boost::parameter::python::function`` we first need to define
a class with forwarding overloads.
::
struct open_fwd
{
template <class A0, class A1, class A2>
void operator()(
boost::type<void>, window& self
, A0 const& a0, A1 const& a1, A2 const& a2
)
{
self.open(a0, a1, a2);
}
};
The first parameter, ``boost::type<void>``, tells the forwarding overload
what the return type should be. In this case we know that it's always void
but in some cases, when we are exporting several specializations of a
Boost.Parameter-enabled template, we need to use that parameter to
deduce the return type.
``window::open()`` takes a total of 3 parameters, so the forwarding function
needs to take three parameters as well.
.. Note::
We only need one overload in the forwarding class, despite the
fact that there are two optional parameters. There are special
circumstances when several overload are needed; see
`special keywords`_.
Next we'll define the module and export the class:
::
BOOST_PYTHON_MODULE(my_module)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<window>("window")
.def(
"open", py::function<
open_fwd
, mpl::vector<
void
, tag::title(std::string)
, tag::width*(unsigned)
, tag::height*(unsigned)
>
>()
);
}
.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
, howmany = 'all'
)
.. @del jam_prefix[:]
``py::function`` is passed two parameters. The first one is the class with
forwarding overloads that we defined earlier. The second one is an `MPL
Sequence`_ with the keyword tag types and argument types for the function
specified as function types. The pointer syntax used in ``tag::width*`` and
``tag::height*`` means that the parameter is optional. The first element of
the `MPL Sequence`_ is the return type of the function, in this case ``void``.
.. The
pointer syntax means that the parameter is optional, so in this case
``width`` and ``height`` are optional parameters. The third parameter
is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
then the parameter types:
.. parsed-literal::
mpl::vector<void, std::string, unsigned, unsigned>
*return type* *title* *width* *height*
.. @ignore()
That's it! This class can now be used in Python with the expected syntax::
>>> w = my_module.window()
>>> w.open(title = "foo", height = 20)
.. @example.prepend('import my_module')
.. @run_python(module_path = my_module)
.. Sorry to say this at such a late date, but this syntax really
.. strikes me as cumbersome. Couldn't we do something like:
class_<window>("window")
.def(
"open",
(void (*)(
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned))
)0
);
or at least:
class_<window>("window")
.def(
"open",
mpl::vector<
void,
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned)
>()
);
assuming, that is, that we will have to repeat the tags (yes,
users of broken compilers will have to give us function pointer
types instead).
------------------------------------------------------------------------------
concept |ParameterSpec|
-----------------------
A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag,
``K``, and the argument type, ``T``, for a parameter.
``K`` is either:
* A *required* keyword of the form ``Tag``
* **or**, an *optional* keyword of the form ``Tag*``
* **or**, a *special* keyword of the form ``Tag**``
where ``Tag`` is a keyword tag type, as used in a specialization
of |keyword|__.
.. |keyword| replace:: ``boost::parameter::keyword``
__ ../../../parameter/doc/html/reference.html#keyword
The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is
defined as the closed range:
.. parsed-literal::
[ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ]
For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``,
the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the
**arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``.
*special* keywords
---------------------------------
Sometimes it is desirable to have a default value for a parameter that differ
in type from the parameter. This technique is useful for doing simple tag-dispatching
based on the presence of a parameter. An example_ of this is given in the Boost.Parameter
docs. The example uses a different technique, but could also have been written like this:
.. parsed-literal::
namespace core
{
template <class ArgumentPack>
void dfs_dispatch(ArgumentPack const& args, mpl::false\_)
{
*…compute and use default color map…*
}
template <class ArgumentPack, class ColorMap>
void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
{
*…use colormap…*
}
}
template <class ArgumentPack>
void depth_first_search(ArgumentPack const& args)
{
core::dfs_dispatch(args, args[color | mpl::false_()]);
}
.. @example.prepend('''
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/mpl/bool.hpp>
#include <cassert>
BOOST_PARAMETER_KEYWORD(tag, color);
typedef boost::parameter::parameters<tag::color> params;
namespace mpl = boost::mpl;
''')
.. @example.replace_emphasis('''
assert(args[color | 1] == 1);
''')
.. @example.replace_emphasis('''
assert(args[color | 1] == 0);
''')
.. @example.append('''
int main()
{
depth_first_search(params()());
depth_first_search(params()(color = 0));
}''')
.. @build()
.. _example: index.html#dispatching-based-on-the-presence-of-a-default
In the above example the type of the default for ``color`` is ``mpl::false_``, a
type that is distinct from any color map that the user might supply.
When binding the case outlined above, the default type for ``color`` will not
be convertible to the parameter type. Therefore we need to tag the ``color``
keyword as a *special* keyword. By doing this we tell the binding functions
that it needs to generate two overloads, one with the ``color`` parameter
present and one without. Had there been two *special* keywords, four
overloads would need to be generated. The number of generated overloads is
equal to 2\ :sup:`N`, where ``N`` is the number of *special* keywords.
------------------------------------------------------------------------------
class template ``init``
-----------------------
Defines a named parameter enabled constructor.
.. parsed-literal::
template <class ParameterSpecs>
struct init : python::def_visitor<init<ParameterSpecs> >
{
template <class Class>
void def(Class& class\_);
template <class CallPolicies>
*def\_visitor* operator[](CallPolicies const& policies) const;
};
.. @ignore()
``init`` requirements
~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element is a
model of |ParameterSpec|.
* For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity
range** of ``ParameterSpecs``, ``Class`` must support these
expressions:
======================= ============= =========================================
Expression Return type Requirements
======================= ============= =========================================
``Class(a0, …, aN)`` \- ``a0``\ …\ ``aN`` are tagged arguments.
======================= ============= =========================================
``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.
Example
~~~~~~~
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
struct base
{
template <class ArgumentPack>
base(ArgumentPack const& args)
{
*… use args …*
}
};
class X : base
{
public:
BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
(required (x, \*))
(optional (y, \*))
)
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<X>("X", no_init)
.def(
py::init<
mpl::vector<tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
''')
.. @example.replace_emphasis('my_module')
.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
class template ``call``
-----------------------
Defines a ``__call__`` operator, mapped to ``operator()`` in C++.
.. parsed-literal::
template <class ParameterSpecs>
struct call : python::def_visitor<call<ParameterSpecs> >
{
template <class Class>
void def(Class& class\_);
template <class CallPolicies>
*def\_visitor* operator[](CallPolicies const& policies) const;
};
.. @ignore()
``call`` requirements
~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``c(…)``.
* ``Class`` must support these expressions, where ``c`` is an
instance of ``Class``:
=================== ==================== =======================================
Expression Return type Requirements
=================== ==================== =======================================
``c(a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
=================== ==================== =======================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.
Example
~~~~~~~
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
namespace parameter = boost::parameter;
typedef parameter::parameters<
parameter::required<tag::x>
, parameter::optional<tag::y>
> call_parameters;
class X
{
public:
template <class ArgumentPack>
int call_impl(ArgumentPack const& args)
{
*… use args …*
}
template <class A0>
int operator()(A0 const& a0)
{
return call_impl(call_parameters()(a0));
}
template <class A0, class A1>
int operator()(A0 const& a0, A1 const& a1)
{
return call_impl(call_parameters()(a0,a1));
}
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = parameter::python;
namespace mpl = boost::mpl;
class_<X>("X")
.def(
py::call<
mpl::vector<int, tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
return 0;
''')
.. @example.replace_emphasis('my_module')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
class template ``function``
---------------------------
Defines a named parameter enabled member function.
.. parsed-literal::
template <class Fwd, class ParameterSpecs>
struct function : python::def_visitor<function<Fwd, ParameterSpecs> >
{
template <class Class, class Options>
void def(Class& class\_, char const* name, Options const& options);
};
.. @ignore()
``function`` requirements
~~~~~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``c.f(…)``, where ``f`` is the member
function.
* An instance of ``Fwd`` must support this expression:
============================================ ==================== =================================================
Expression Return type Requirements
============================================ ==================== =================================================
``fwd(boost::type<R>(), self, a0, …, aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
the function should be invoked. ``a0``\ …\ ``aN``
are tagged arguments.
============================================ ==================== =================================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
Example
~~~~~~~
This example exports a member function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
class X
{
public:
BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
(required (x, \*))
(optional (y, \*, 1))
)
{
*…*
}
};
struct f_fwd
{
template <class A0, class A1>
void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1)
{
self.f(a0, a1);
}
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<X>("X")
.def("f",
py::function<
f_fwd
, mpl::vector<void, tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(x == 0);
assert(y == 1);
''')
.. @example.replace_emphasis('my_module')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
function template ``def``
-------------------------
Defines a named parameter enabled free function in the current Python scope.
.. parsed-literal::
template <class Fwd, class ParameterSpecs>
void def(char const* name);
.. @ignore()
``def`` requirements
~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``f(…)``, where ``f`` is the function.
* An instance of ``Fwd`` must support this expression:
====================================== ==================== =======================================
Expression Return type Requirements
====================================== ==================== =======================================
``fwd(boost::type<R>(), a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
====================================== ==================== =======================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
Example
~~~~~~~
This example exports a function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.
.. parsed-literal::
BOOST_PARAMETER_FUNCTION((void), f, tag,
(required (x, \*))
(optional (y, \*, 1))
)
{
*…*
}
struct f_fwd
{
template <class A0, class A1>
void operator()(boost::type<void>, A0 const& a0, A1 const& a1)
{
f(a0, a1);
}
};
BOOST_PYTHON_MODULE(…)
{
def<
f_fwd
, mpl::vector<
void, tag::\ x(int), tag::\ y\*(int)
>
>("f");
}
.. @ignore()
.. again, the undefined ``fwd`` identifier.
Portability
-----------
The Boost.Parameter Python binding library requires *partial template
specialization*.

View File

@@ -2,13 +2,6 @@
The Boost Parameter Library Reference Documentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|(logo)|__
.. |(logo)| image:: ../../../../boost.png
:alt: Boost
__ ../../../../index.htm
:Authors: David Abrahams, Daniel Wallin
:Contact: dave@boost-consulting.com, dalwan01@student.umu.se
:organization: `Boost Consulting`_
@@ -19,6 +12,13 @@ __ ../../../../index.htm
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
.. _`Boost Consulting`: http://www.boost-consulting.com
@@ -253,7 +253,7 @@ argument type. In each row,
+----------------------+--------------+--------------------------------+
|Type |``A`` required|Condition ``A`` must satisfy |
+======================+==============+================================+
||keyword|_\ ``<K>`` |no |*n/a* |
|``K`` |no |*n/a* |
+----------------------+--------------+--------------------------------+
||optional|_\ ``<K,F>``|no |``mpl::apply<F,A>::type::value``|
| | |is ``true``. |
@@ -381,16 +381,15 @@ __ ../../../../boost/parameter/parameters.hpp
};
template <class A0>
|ArgumentPack|_ `operator()`_\(A0 const& a0) const;
|ArgumentPack|_ `operator()`_\(A0& a0) const;
template <class A0, class A1>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1) const; :vellipsis:`\
.
.
.
`
|ArgumentPack|_ `operator()`_\(A0& a0, A1& a1) const;
:vellipsis:`⋮`
template <class A0, class A1, …class A\ β>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1, …A\ β const& a\ β) const;
|ArgumentPack|_ `operator()`_\(A0& a0, A1& a1, …A\ β& a\ β) const;
};
@@ -403,13 +402,22 @@ __ ../../../../boost/parameter/parameters.hpp
follows, for any argument type ``A``\ *i*:
| let ``D0`` the set [d0, …, d\ *j*] of all **deduced** *parameter specs* in [``P0``, …, ``P``\ β]
| ``R``\ *i* is ``A``\ *i*\ 's |intended argument type|
|
| if ``A``\ *i* is a result type of ``keyword<T>::``\ |operator=|_
| then
| ``K``\ *i* is ``T``
| else
| ``K``\ *i* is ``P``\ *i*\ 's |keyword tag type|.
| if ``A``\ *i* is a result type of ``keyword<T>::``\ |operator=|_
| then
| ``K``\ *i* is ``T``
| else
| if some ``A``\ *j* where *j*\ ≤\ *i* is a result type of ``keyword<T>::``\ |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 ``d``\ *j*\ 's |keyword tag type|.
| ``D``\ :sub:`i+1` is ``D``\ *i* - [``d``\ *j*]
| else
| ``K``\ *i* is ``P``\ *i*\ 's |keyword tag type|.
.. _match:
@@ -425,7 +433,7 @@ __ ../../../../boost/parameter/parameters.hpp
every *j* in 0…β, either:
* ``P``\ *j* is the *unspecified* default
* **or**, ``P``\ *j* is a specialization of |keyword|_,
* **or**, ``P``\ *j* is a *keyword tag type*
* **or**, ``P``\ *j* is |optional|_ ``<X,F>`` and either
@@ -443,11 +451,10 @@ __ ../../../../boost/parameter/parameters.hpp
``operator()``
.. parsed-literal::
template <class A0> |ArgumentPack|_ operator()(A0 const& a0) const; :vellipsis:`\
.
.
.
`
template <class A0> |ArgumentPack|_ operator()(A0 const& a0) const;
:vellipsis:`⋮`
template <class A0, …class A\ β> |ArgumentPack|_ `operator()`_\(A0 const& a0, …A\ β const& a\ β) const;
:Returns:
@@ -488,6 +495,23 @@ The default value of ``Predicate`` is an unspecified |Metafunction|_ that return
.. |Metafunction| replace:: :concept:`Metafunction`
.. _Metafunction: ../../../mpl/doc/refmanual/metafunction.html
``deduced``
-----------
This template is used to wrap the *keyword tag* argument to
``optional`` or ``required``.
:Defined in: `boost/parameter/parameters.hpp`__
__ ../../../../boost/parameter/parameters.hpp
.. parsed-literal::
template <class Tag>
struct deduced;
//////////////////////////////////////////////////////////////////////////////
Metafunctions
@@ -546,6 +570,37 @@ __ ../../../../boost/parameter/binding.hpp
reference| exists, returns ``boost::``\ |result_of|_\ ``<F()>::type``. [#no_result_of]_
``value_type``
--------------
Returns the result type of indexing an argument pack with a
|keyword tag type| or with a |tagged default|.
:Defined n: `boost/parameter/value_type.hpp`__
__ ../../../../boost/parameter/value_type.hpp
.. parsed-literal::
template <class A, class K, class D = void>
struct value_type
{
typedef … type;
};
:Requires: ``A`` is a model of |ArgumentPack|_.
:Returns: the type of the |tagged reference| in ``A``
having |keyword tag type| ``K``, if any. If no such |tagged
reference| exists, returns ``D``. Equivalent to::
typename remove_reference<
typename binding<A, K, D>::type
>::type
… when ``D`` is not a reference type.
//////////////////////////////////////////////////////////////////////////////
Code Generation Macros
@@ -554,9 +609,256 @@ Code Generation Macros
Macros in this section can be used to ease the writing of code
using the Parameter libray by eliminating repetitive boilerplate.
``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``
-----------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
:Requires: ``result`` is the parenthesized return type of the function.
``name`` is the base name of the function, this is the name of the
generated forwarding functions. ``tag_namespace`` is the namespace in
which the keywords used by the function resides. ``arguments`` is
a list of *argument specifiers*, as defined below.
:Argument specifiers syntax:
.. parsed-literal::
argument-specifiers ::= *specifier-group* {*specifier-group*}
specifier-group0 ::= *specifier-group1* |
( '**(**' '**deduced**' *specifier-group1* {*specifier-group1*} '**)**' )
specifier-group1 ::= ( '**(**' '**optional**' *optional-specifier* {*optional-specifier*} '**)**' ) |
( '**(**' '**required**' *required-specifier* {*required-specifier*} '**)**' )
optional-specifier ::= '**(**' *name* '**,**' *restriction* '**,**' *default-value* ')'
required-specifier ::= '**(**' *name* '**,**' *restriction* ')'
restriction ::= ('*****' '**(**' *lambda-expression* '**)**' ) |
( '**(**' *typename* '**)**' ) |
'*****'
``name`` is any valid C++ identifier. ``default-value`` is any valid
C++ expression. ``typename`` is the name of a type.
``lambda-expression`` is an `MPL lambda expression`_.
.. _`MPL lambda expression`: ../../../mpl/doc/refmanual/lambda-expression.html
:Generated names in enclosing scope:
* ``boost_param_result_ ## __LINE__ ## name``
* ``boost_param_params_ ## __LINE__ ## name``
* ``boost_param_parameters_ ## __LINE__ ## name``
* ``boost_param_impl ## name``
* ``boost_param_default_ ## __LINE__ ## name``
Approximate expansion:
**Where**:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
template <class T>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: boost::parameter::parameters<
*list of parameter specifications, based on arguments*
>
{};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <class A0, …, class A\ **n**>
*result type* **name**\ (
A0 *cv*\ & a0, …, A\ **n** *cv*\ & a\ **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**::match<
A0 *cv*, …, A\ **n** *cv*
>::type = boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
*… forward to implementation …*
}
:vellipsis:`⋮`
template <class A0, …, class A\ **m**>
*result type* **name**\ (
A0 *cv*\ & a0, …, A\ **m** *cv*\ & a\ **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**::match<
A0 *cv*, …, A\ **m** *cv*
>::type = boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
*… forward to implementation …*
}
template <
class ResultType
, class *argument name*\ **0** ## _type
, class *argument name*\ **m** ## _type
>
ResultType boost_param_default\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, *argument name*\ **0** ## _type& *argument name*\ **0**
, *argument name*\ **m** ## _type& *argument name*\ **m**
)
``BOOST_PARAMETER_MEMBER_FUNCTION(result,name,tag_namespace,arguments)``
------------------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
See ``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``
``BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, arguments)``
--------------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
:Requires: ``cls`` is the name of this class. ``impl`` is the
parenthesized implementation base class for ``cls``.
``tag_namespace`` is the namespace in which the keywords
used by the function resides. ``arguments`` is
a list of *argument specifiers*, as defined in
``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``.
:Generated names in enclosing scope:
* ``boost_param_params_ ## __LINE__ ## ctor``
* ``constructor_parameters ## __LINE__``
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
: boost::parameter::parameters<
*list of parameter specifications, based on arguments*
>
{};
typedef boost_param_params\_ ## __LINE__ ## **name**
constructor_parameters ## __LINE__;
template <class A0, …, class A\ **n**>
*cls*\ (A0 const& a0, …, A\ **n** const& a\ **n**)
: *impl*\ (constructor_parameters ## __LINE__(a0, …, a\ **n**))
{}
:vellipsis:`⋮`
template <class A0, …, class A\ **m**>
*cls*\ (A0 const& a0, …, A\ **n** const& a\ **m**)
: *impl*\ (constructor_parameters ## __LINE__(a0, …, a\ **m**))
{}
``BOOST_PARAMETER_NAME(name)``
------------------------------
Declares a tag-type and keyword object.
Expands to:
**If** *name* is of the form:
.. parsed-literal::
(*tag-name*, *namespace-name*) *object-name*
**then**
.. parsed-literal::
namespace *namespace-name*
{
struct *tag-name*
{
static char const* keyword_name()
{
return ##\ *tag-name*;
}
typedef *implementation defined* _;
typedef *implementation defined* _1;
};
}
::boost::parameter::keyword<*tag-namespace*\ ::\ *tag-name*\ > const& *object-name*
= ::boost::parameter::keyword<*tag-namespace*\ ::\ *tag-name*\ >::instance;
**Else**
.. parsed-literal::
namespace tag
{
struct *name*
{
static char const* keyword_name()
{
return ##\ *name*;
}
typedef *implementation defined* _;
typedef *implementation defined* _1;
};
}
::boost::parameter::keyword<tag::\ *name*\ > const& _\ *name*
= ::boost::parameter::keyword<tag::\ *name*\ >::instance;
``BOOST_PARAMETER_TEMPLATE_KEYWORD(name)``
------------------------------------------
Expands to:
.. parsed-literal::
namespace tag
{
struct *name*;
}
template <class T>
struct *name*
: ::boost::parameter::template_keyword<tag::\ *name*, T>
{};
``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
@@ -587,11 +889,10 @@ Generates
, typename **p**::match<A1,A2,…A\ **l**,A\ ##\ BOOST_PP_INC_\ (**l**)>::type p = **p**\ ())
{
return **name**\ _with_named_params(**p**\ (x1,x2,…x\ **l**,x\ ##\ BOOST_PP_INC_\ (**l**)));
} :vellipsis:`\
.
.
.
`
}
:vellipsis:`⋮`
template <class A1, class A2, …class A\ **h**>
r name(
A1 const& a1, A2 const& a2, …A\ **h** const& x\ **h**
@@ -606,6 +907,11 @@ Generates
``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.
@@ -691,4 +997,5 @@ __ index.html#tutorial
.. _result_of: ../../../utility/utility.htm#result_of
.. |BOOST_NO_RESULT_OF| replace:: ``BOOST_NO_RESULT_OF``
.. _BOOST_NO_RESULT_OF: ../../../utility/utility.htm#BOOST_NO_RESULT_OF
.. _BOOST_NO_RESULT_OF: ../../../utility/utility.htm#BOOST_NO_RESULT_OF

View File

@@ -9,8 +9,11 @@
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/value_type.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/parameter/match.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/preprocessor.hpp>
#endif // BOOST_PARAMETER_050401_HPP

View File

@@ -32,6 +32,9 @@ template<class T> struct keyword;
namespace aux {
// Tag type passed to MPL lambda.
struct lambda_tag;
//
// Structures used to build the tuple of actual arguments. The
// tuple is a nested cons-style list of arg_list specializations
@@ -67,7 +70,7 @@ struct empty_arg_list
// lookup given that default
struct binding
{
template<class KW, class Default>
template<class KW, class Default, class Reference>
struct apply
{
typedef Default type;
@@ -137,9 +140,9 @@ struct empty_arg_list
// was found if we match this overload, so unless that parameter
// has a default, we indicate that the actual arguments don't
// match the function's requirements.
template <class ParameterRequirements>
template <class ParameterRequirements, class ArgPack>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
satisfies(ParameterRequirements*, ArgPack*);
// MPL sequence support
typedef empty_arg_list type; // convenience
@@ -176,7 +179,7 @@ template <class TaggedArg, class Next = empty_arg_list>
struct arg_list : Next
{
typedef arg_list<TaggedArg,Next> self;
typedef typename TaggedArg::key_type key_type;
typedef typename TaggedArg::key_type key_type;
typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;
@@ -221,13 +224,13 @@ struct arg_list : Next
// lookup given that default
struct binding
{
template <class KW, class Default>
template <class KW, class Default, class Reference>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
, mpl::if_<Reference, reference, value_type>
, mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
>::type type;
};
};
@@ -297,7 +300,7 @@ struct arg_list : Next
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap2<binding, KW, void_>::type
typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
operator[](keyword<KW> const& x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
@@ -305,7 +308,7 @@ struct arg_list : Next
}
template <class KW, class Default>
typename mpl::apply_wrap2<binding, KW, Default&>::type
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
operator[](default_<KW, Default> x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
@@ -313,9 +316,10 @@ struct arg_list : Next
}
template <class KW, class F>
typename mpl::apply_wrap2<
typename mpl::apply_wrap3<
binding,KW
, typename result_of0<F>::type
, mpl::true_
>::type
operator[](lazy_default<KW,F> x) const
{
@@ -381,10 +385,14 @@ struct arg_list : Next
// compile-time computation and never really called, so a
// declaration is enough.
//
template <class HasDefault, class Predicate>
static typename mpl::apply1<Predicate, value_type>::type
template <class HasDefault, class Predicate, class ArgPack>
static typename mpl::apply_wrap2<
typename mpl::lambda<Predicate, lambda_tag>::type
, value_type, ArgPack
>::type
satisfies(
parameter_requirements<key_type,Predicate,HasDefault>*
, ArgPack*
);
// Builds an overload set including satisfies functions defined

View File

@@ -0,0 +1,129 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#ifndef BOOST_PARAMETER_CAST_060902_HPP
# define BOOST_PARAMETER_CAST_060902_HPP
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/remove_const.hpp>
# endif
namespace boost { namespace parameter { namespace aux {
struct use_default_tag {};
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value
# else
// Handles possible implicit casts. Used by preprocessor.hpp to
// normalize user input.
//
// cast<void*>::execute() is identity
// cast<void*(X)>::execute() is identity
// cast<void(X)>::execute() casts to X
//
// preprocessor.hpp uses this like this:
//
// #define X(value, predicate)
// cast<void predicate>::execute(value)
//
// X(something, *)
// X(something, *(predicate))
// X(something, (int))
template <class T>
struct cast;
template <>
struct cast<void*>
{
static use_default_tag execute(use_default_tag)
{
return use_default_tag();
}
static use_default_tag remove_const(use_default_tag)
{
return use_default_tag();
}
template <class U>
static U& execute(U& value)
{
return value;
}
template <class U>
static U& remove_const(U& x)
{
return x;
}
};
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
typedef void* voidstar;
template <class T>
struct cast<voidstar(T)>
: cast<void*>
{
};
#else
template <class T>
struct cast<void*(T)>
: cast<void*>
{
};
#endif
template <class T>
struct cast<void(T)>
{
typedef typename boost::add_reference<
typename boost::remove_const<T>::type
>::type reference;
static use_default_tag execute(use_default_tag)
{
return use_default_tag();
}
static use_default_tag remove_const(use_default_tag)
{
return use_default_tag();
}
static T execute(T value)
{
return value;
}
template <class U>
static reference remove_const(U const& x)
{
return const_cast<reference>(x);
}
};
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) \
boost::parameter::aux::cast<void predicate>::remove_const( \
boost::parameter::aux::cast<void predicate>::execute(value) \
)
# endif
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_CAST_060902_HPP

View File

@@ -9,9 +9,10 @@
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/optional.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/type_traits/add_const.hpp>
namespace boost { namespace parameter { namespace aux {
@@ -20,14 +21,18 @@ struct maybe_base {};
template <class T>
struct maybe : maybe_base
{
typedef typename mpl::if_<
is_reference<T>
, T
, typename add_reference<
typename add_const<T>::type
>::type
typedef typename add_reference<
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
T const
# else
typename add_const<T>::type
# endif
>::type reference;
typedef typename remove_cv<
BOOST_DEDUCED_TYPENAME remove_reference<reference>::type
>::type non_cv_value;
explicit maybe(T value)
: value(value)
, constructed(false)
@@ -40,7 +45,7 @@ struct maybe : maybe_base
~maybe()
{
if (constructed)
destroy((void(*)(reference))0);
this->destroy();
}
reference construct(reference value) const
@@ -48,24 +53,23 @@ struct maybe : maybe_base
return value;
}
template <class U, class V>
reference construct(U const& value, void(*)(V&)) const
template <class U>
reference construct2(U const& value) const
{
new (m_storage.bytes) V(value);
new (m_storage.bytes) non_cv_value(value);
constructed = true;
return *(V*)m_storage.bytes;
return *(non_cv_value*)m_storage.bytes;
}
template <class U>
reference construct(U const& value) const
{
return construct(value, (void(*)(reference))0);
return this->construct2(value);
}
template <class U>
void destroy(void(*)(U&))
void destroy()
{
((U*)m_storage.bytes)->~U();
((non_cv_value*)m_storage.bytes)->~non_cv_value();
}
typedef reference(maybe<T>::*safe_bool)() const;

View File

@@ -44,26 +44,37 @@
#define N BOOST_PP_ITERATION()
#define BOOST_PARAMETER_open_list(z, n, text) \
aux::make_arg_list< \
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n), aux::tag_keyword_arg
aux::item< \
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n)
#define BOOST_PARAMETER_close_list(z, n, text) >
#define BOOST_PARAMETER_arg_list(n) \
mpl::apply_wrap1< \
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
, mpl::always<aux::empty_arg_list> \
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \
, unnamed_list>
aux::make_arg_list< \
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
, void_ \
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \
, deduced_list \
, aux::tag_keyword_arg \
>
#define BOOST_PARAMETER_arg_pack_init(z, n, limit) \
BOOST_PP_CAT(a, BOOST_PP_SUB(limit,n))
template<BOOST_PP_ENUM_PARAMS(N, class A)>
typename BOOST_PARAMETER_arg_list(N)::type
typename mpl::first<
typename BOOST_PARAMETER_arg_list(N)::type
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, & a)) const
{
typedef typename BOOST_PARAMETER_arg_list(N)::type arg_tuple;
typedef typename BOOST_PARAMETER_arg_list(N)::type result;
return arg_tuple(
BOOST_PP_ENUM_PARAMS(N, a)
typedef typename mpl::first<result>::type result_type;
typedef typename mpl::second<result>::type error;
error();
return result_type(
BOOST_PP_ENUM(N, BOOST_PARAMETER_arg_pack_init, BOOST_PP_DEC(N))
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N)
, aux::void_reference() BOOST_PP_INTERCEPT

View File

@@ -0,0 +1,119 @@
// Copyright David Abrahams 2006. 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)
#ifndef BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
# define BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
# include <boost/config.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace parameter { namespace aux {
// A macro that takes a parenthesized C++ type name (T) and transforms
// it into an un-parenthesized type expression equivalent to T.
# define BOOST_PARAMETER_PARENTHESIZED_TYPE(x) \
boost::parameter::aux::unaryfunptr_arg_type< void(*)x >::type
// A metafunction that transforms void(*)(T) -> T
template <class UnaryFunctionPointer>
struct unaryfunptr_arg_type;
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <class Arg>
struct unaryfunptr_arg_type<void(*)(Arg)>
{
typedef Arg type;
};
# else
// Use the "native typeof" bugfeatures of older versions of MSVC to
// accomplish what we'd normally do with partial specialization. This
// capability was discovered by Igor Chesnokov.
# if BOOST_WORKAROUND(BOOST_MSVC, != 1300)
// This version applies to VC6.5 and VC7.1 (except that we can just
// use partial specialization for the latter in this case).
// This gets used as a base class.
template<typename Address>
struct msvc_type_memory
{
// A nullary metafunction that will yield the Value type "stored"
// at this Address.
struct storage;
};
template<typename Value, typename Address>
struct msvc_store_type : msvc_type_memory<Address>
{
// VC++ somehow lets us define the base's nested storage
// metafunction here, where we have the Value type we'd like to
// "store" in it. Later we can come back to the base class and
// extract the "stored type."
typedef msvc_type_memory<Address> location;
struct location::storage
{
typedef Value type;
};
};
# else
// This slightly more complicated version of the same thing is
// required for msvc-7.0
template<typename Address>
struct msvc_type_memory
{
template<bool>
struct storage_impl;
typedef storage_impl<true> storage;
};
template<typename Value, typename Address>
struct msvc_store_type : msvc_type_memory<Address>
{
// Rather than supplying a definition for the base class' nested
// class, we specialize the base class' nested template
template<>
struct storage_impl<true>
{
typedef Value type;
};
};
# endif
// Function template argument deduction does many of the same things
// as type matching during partial specialization, so we call a
// function template to "store" T into the type memory addressed by
// void(*)(T).
template <class T>
msvc_store_type<T,void(*)(T)>
msvc_store_argument_type(void(*)(T));
template <class FunctionPointer>
struct unaryfunptr_arg_type
{
// We don't want the function to be evaluated, just instantiated,
// so protect it inside of sizeof.
enum { dummy = sizeof(msvc_store_argument_type((FunctionPointer)0)) };
// Now pull the type out of the instantiated base class
typedef typename msvc_type_memory<FunctionPointer>::storage::type type;
};
# endif
template <>
struct unaryfunptr_arg_type<void(*)(void)>
{
typedef void type;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP

View File

@@ -9,14 +9,16 @@
# include <boost/preprocessor/tuple/rem.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/seq/for_each.hpp>
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/identity.hpp>
# include <boost/preprocessor/selection/max.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/repetition/enum_trailing.hpp>
# include <boost/parameter/aux_/preprocessor/for_each.hpp>
# define BOOST_PARAMETER_FLATTEN_SPLIT_required required,
# define BOOST_PARAMETER_FLATTEN_SPLIT_optional optional,
# define BOOST_PARAMETER_FLATTEN_SPLIT_deduced deduced,
# define BOOST_PARAMETER_FLATTEN_SPLIT(sub) \
BOOST_PP_CAT(BOOST_PARAMETER_FLATTEN_SPLIT_, sub)
@@ -48,16 +50,18 @@
) \
))
# define BOOST_PARAMETER_FLATTEN_SPEC_AUX(r, arity, max_arity, spec) \
# define BOOST_PARAMETER_FLATTEN_SPEC_AUX(r, arity, max_arity, spec, transform) \
BOOST_PARAMETER_FOR_EACH_R( \
r \
, arity \
, BOOST_PARAMETER_FLATTEN_ARGS(spec) \
, (arity, max_arity, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec)) \
, (arity, max_arity, transform(BOOST_PARAMETER_FLATTEN_QUALIFIER(spec))) \
, BOOST_PARAMETER_FLATTEN_SPEC0 \
)
# define BOOST_PARAMETER_FLATTEN_SPEC(r, arities, spec) \
# define BOOST_PARAMETER_FLATTEN_IDENTITY(x) x
# define BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_AUX( \
r \
, BOOST_PP_CAT( \
@@ -65,14 +69,44 @@
)(arities) \
, BOOST_PP_TUPLE_ELEM(3,2,arities) \
, spec \
, BOOST_PARAMETER_FLATTEN_IDENTITY \
)
# define BOOST_PARAMETER_FLATTEN(optional_arity, required_arity, specs) \
# define BOOST_PARAMETER_FLATTEN_SPEC_required(r, arities, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec)
# define BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED(x) BOOST_PP_CAT(deduced_,x)
# define BOOST_PARAMETER_FLATTEN_SPEC_deduced_M(r, arities, n, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_AUX( \
r \
, BOOST_PP_CAT( \
BOOST_PARAMETER_FLATTEN_ARITY_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \
)(arities) \
, BOOST_PP_TUPLE_ELEM(3,2,arities) \
, spec \
, BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED \
)
# define BOOST_PARAMETER_FLATTEN_SPEC_deduced(r, arities, spec) \
BOOST_PP_SEQ_FOR_EACH_I_R( \
r \
, BOOST_PARAMETER_FLATTEN_SPEC_deduced_M \
, arities \
, BOOST_PARAMETER_FLATTEN_ARGS(spec) \
)
# define BOOST_PARAMETER_FLATTEN_SPEC(r, arities, spec) \
BOOST_PP_CAT( \
BOOST_PARAMETER_FLATTEN_SPEC_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \
)(r, arities, spec)
# define BOOST_PARAMETER_FLATTEN(optional_arity, required_arity, wanted_arity, specs) \
BOOST_PP_SEQ_FOR_EACH( \
BOOST_PARAMETER_FLATTEN_SPEC \
, ( \
optional_arity, required_arity \
, BOOST_PP_MAX(optional_arity, required_arity) \
, wanted_arity \
) \
, specs \
)

View File

@@ -14,6 +14,7 @@
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/punctuation/comma_if.hpp>
# include <boost/preprocessor/for.hpp>
# include <boost/preprocessor/repetition/deduce_r.hpp>
# define BOOST_PARAMETER_FOR_EACH_head_aux2(x,y) (x,y), ~
# define BOOST_PARAMETER_FOR_EACH_head_aux3(x,y,z) (x,y,z), ~

View File

@@ -85,9 +85,9 @@ struct invoker<0, M, R, Args>
template <class M, class R, class T, class Args>
struct member_invoker<0, M, R, T, Args>
{
static R execute()
static R execute(T& self)
{
return M()(boost::type<R>());
return M()(boost::type<R>(), self);
}
};

View File

@@ -0,0 +1,65 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#ifndef BOOST_PARAMETER_SET_060912_HPP
# define BOOST_PARAMETER_SET_060912_HPP
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
&& !BOOST_WORKAROUND(__GNUC__, < 3)
# include <boost/mpl/insert.hpp>
# include <boost/mpl/set/set0.hpp>
# include <boost/mpl/has_key.hpp>
namespace boost { namespace parameter { namespace aux {
typedef mpl::set0<> set0;
template <class Set, class K>
struct insert_
{
typedef typename mpl::insert<Set, K>::type type;
};
template <class Set, class K>
struct has_key_
{
typedef typename mpl::has_key<Set, K>::type type;
};
}}} // namespace boost::parameter::aux
# else
# include <boost/mpl/list.hpp>
# include <boost/mpl/end.hpp>
# include <boost/mpl/find.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/push_front.hpp>
namespace boost { namespace parameter { namespace aux {
typedef mpl::list0<> set0;
template <class Set, class K>
struct insert_
{
typedef typename mpl::push_front<Set, K>::type type;
};
template <class Set, class K>
struct has_key_
{
typedef typename mpl::find<Set, K>::type iter;
typedef mpl::not_<
is_same<iter, typename mpl::end<Set>::type>
> type;
};
}}} // namespace boost::parameter::aux
# endif
#endif // BOOST_PARAMETER_SET_060912_HPP

View File

@@ -21,11 +21,13 @@ namespace boost { namespace parameter { namespace aux {
struct empty_arg_list;
struct arg_list_tag;
struct tagged_argument_base {};
// Holds a reference to an argument of type Arg associated with
// keyword Keyword
template <class Keyword, class Arg>
struct tagged_argument
struct tagged_argument : tagged_argument_base
{
typedef Keyword key_type;
typedef Arg value_type;
@@ -38,13 +40,13 @@ struct tagged_argument
// lookup given that default
struct binding
{
template <class KW, class Default>
template <class KW, class Default, class Reference>
struct apply
{
typedef typename mpl::if_<
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, reference
, Default
, mpl::if_<Reference, reference, value_type>
, mpl::identity<Default>
>::type type;
};
};
@@ -72,7 +74,7 @@ struct tagged_argument
return value;
}
# ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
# if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class KW, class Default>
Default& get_with_default(default_<KW,Default> const& x, int) const
{
@@ -86,7 +88,7 @@ struct tagged_argument
}
template <class KW, class Default>
typename mpl::apply_wrap2<binding, KW, Default&>::type
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
operator[](default_<KW,Default> const& x) const
{
return get_with_default(x, 0L);
@@ -106,9 +108,10 @@ struct tagged_argument
}
template <class KW, class F>
typename mpl::apply_wrap2<
typename mpl::apply_wrap3<
binding,KW
, typename result_of0<F>::type
, mpl::true_
>::type
operator[](lazy_default<KW,F> const& x) const
{
@@ -163,23 +166,12 @@ struct tagged_argument
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
template <class K, class T>
char is_tagged_argument_check(tagged_argument<K,T> const*);
char(&is_tagged_argument_check(...))[2];
// Defines a metafunction, is_tagged_argument, that identifies
// tagged_argument specializations.
// MAINTAINER NOTE: Not using BOOST_DETAIL_IS_XXX_DEF here because
// we need to return true for tagged_argument<K,T> const.
// tagged_argument specializations and their derived classes.
template <class T>
struct is_tagged_argument_aux
{
enum { value =
sizeof(is_tagged_argument_check((T*)0)) == 1
};
typedef mpl::bool_<value> type;
};
: is_convertible<T*,tagged_argument_base const*>
{};
template <class T>
struct is_tagged_argument

View File

@@ -9,22 +9,25 @@
# include <boost/mpl/and.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_same.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/mpl/eval_if.hpp>
# endif
namespace boost { namespace parameter {
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns Default
template <class Parameters, class Keyword, class Default = void_>
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct binding
# else
struct binding_eti
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct binding0
{
typedef typename mpl::apply_wrap2<
typename Parameters::binding,Keyword,Default
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::true_
>::type type;
BOOST_MPL_ASSERT_NOT((
@@ -34,6 +37,39 @@ struct binding_eti
>
));
};
# endif
template <class Parameters, class Keyword, class Default = void_>
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct binding
# else
struct binding_eti
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
, binding0<Parameters,Keyword,Default>
>::type type;
# else
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::true_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
# endif
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class Parameters, class Keyword, class Default = void_>
@@ -44,6 +80,8 @@ struct binding
, mpl::identity<int>
, binding_eti<Parameters, Keyword, Default>
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
};
# endif
@@ -54,10 +92,11 @@ struct binding
template <class Parameters, class Keyword, class DefaultFn>
struct lazy_binding
{
typedef typename mpl::apply_wrap2<
typedef typename mpl::apply_wrap3<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
, mpl::true_
>::type type;
};

View File

@@ -9,7 +9,6 @@
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/noncopyable.hpp>
namespace boost { namespace parameter {
@@ -29,7 +28,7 @@ namespace boost { namespace parameter {
// f(rate = 1, skew = 2.4);
//
template <class Tag>
struct keyword : noncopyable
struct keyword
{
template <class T>
typename aux::tag<Tag, T>::type const
@@ -98,9 +97,6 @@ struct keyword : noncopyable
static keyword<Tag> result;
return result;
}
private:
keyword() {}
};
// Reduces boilerplate required to declare and initialize keywords

155
include/boost/parameter/name.hpp Executable file
View File

@@ -0,0 +1,155 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#ifndef BOOST_PARAMETER_NAME_060806_HPP
# define BOOST_PARAMETER_NAME_060806_HPP
# include <boost/parameter/keyword.hpp>
# include <boost/parameter/value_type.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/stringize.hpp>
# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/tuple/eat.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/mpl/placeholders.hpp>
# if !defined(BOOST_NO_SFINAE) \
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include <boost/utility/enable_if.hpp>
# include <boost/mpl/lambda.hpp>
namespace boost { namespace parameter { namespace aux {
// Tag type passed to MPL lambda.
struct lambda_tag;
struct name_tag_base
{};
template <class Tag>
struct name_tag
{};
template <class T>
struct is_name_tag
: mpl::false_
{};
}}} // namespace boost::parameter::aux
namespace boost { namespace mpl {
template <class T>
struct lambda<
T
, typename enable_if<
parameter::aux::is_name_tag<T>, parameter::aux::lambda_tag
>::type
>
{
typedef true_ is_le;
typedef bind3< quote3<parameter::value_type>, arg<2>, T, void> result_;
typedef result_ type;
};
}} // namespace boost::mpl
# endif
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/preprocessor/detail/split.hpp>
// From Paul Mensonides
# define BOOST_PARAMETER_IS_BINARY(x) \
BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_BINARY_C x BOOST_PP_COMMA() 0) \
/**/
# define BOOST_PARAMETER_IS_BINARY_C(x,y) \
~, 1 BOOST_PP_RPAREN() \
BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \
/**/
# else
# include <boost/preprocessor/detail/is_binary.hpp>
# define BOOST_PARAMETER_IS_BINARY(x) BOOST_PP_IS_BINARY(x)
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# define BOOST_PARAMETER_NAME_OBJECT(tag, name) \
static ::boost::parameter::keyword<tag>& name \
= ::boost::parameter::keyword<tag>::get();
# else
# define BOOST_PARAMETER_NAME_OBJECT(tag, name) \
namespace \
{ \
::boost::parameter::keyword<tag>& name \
= ::boost::parameter::keyword<tag>::get(); \
}
# endif
# define BOOST_PARAMETER_BASIC_NAME(tag_namespace, tag, name) \
namespace tag_namespace \
{ \
struct tag \
{ \
static char const* keyword_name() \
{ \
return BOOST_PP_STRINGIZE(tag); \
} \
\
typedef boost::parameter::value_type< \
boost::mpl::_2, tag, boost::parameter::void_ \
> _; \
\
typedef boost::parameter::value_type< \
boost::mpl::_2, tag, boost::parameter::void_ \
> _1; \
}; \
} \
BOOST_PARAMETER_NAME_OBJECT(tag_namespace::tag, name)
# define BOOST_PARAMETER_COMPLEX_NAME_TUPLE1(tag,namespace) \
(tag, namespace), ~
# define BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name) \
BOOST_PP_TUPLE_ELEM(2, 0, (BOOST_PARAMETER_COMPLEX_NAME_TUPLE1 name))
# define BOOST_PARAMETER_COMPLEX_NAME_TAG(name) \
BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name))
# define BOOST_PARAMETER_COMPLEX_NAME_NAMESPACE(name) \
BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name))
# define BOOST_PARAMETER_COMPLEX_NAME(name) \
BOOST_PARAMETER_BASIC_NAME( \
BOOST_PARAMETER_COMPLEX_NAME_NAMESPACE(name) \
, BOOST_PP_TUPLE_EAT(2) name \
, BOOST_PARAMETER_COMPLEX_NAME_TAG(name) \
) \
/**/
# define BOOST_PARAMETER_SIMPLE_NAME(name) \
BOOST_PARAMETER_BASIC_NAME(tag, name, BOOST_PP_CAT(_, name))
# define BOOST_PARAMETER_NAME(name) \
BOOST_PP_IIF( \
BOOST_PARAMETER_IS_BINARY(name) \
, BOOST_PARAMETER_COMPLEX_NAME \
, BOOST_PARAMETER_SIMPLE_NAME \
)(name) \
/**/
# define BOOST_PARAMETER_TEMPLATE_KEYWORD(name) \
namespace tag \
{ \
struct name; \
} \
template <class T> \
struct name \
: boost::parameter::template_keyword<tag::name, T> \
{}; \
/**/
#endif // BOOST_PARAMETER_NAME_060806_HPP

View File

@@ -8,6 +8,8 @@
#include <boost/detail/is_xxx.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/always.hpp>
@@ -26,6 +28,7 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
@@ -42,8 +45,19 @@
#include <boost/parameter/aux_/tagged_argument.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/aux_/template_keyword.hpp>
#include <boost/parameter/aux_/set.hpp>
#include <boost/parameter/config.hpp>
namespace parameter_
{
template <class T>
struct unmatched_argument
{
BOOST_MPL_ASSERT((boost::is_same<T,void>));
typedef int type;
};
} // namespace parameter_
namespace boost {
template<class T> class reference_wrapper;
@@ -67,7 +81,7 @@ namespace aux { struct use_default {}; }
// required<...>, wrapper, it is treated as though optional<k> were
// specified.
//
// If a keyword k is specified with unnamed<...>, that keyword
// If a keyword k is specified with deduced<...>, that keyword
// will be automatically deduced from the argument list.
//
template <class Tag, class Predicate = aux::use_default>
@@ -84,20 +98,37 @@ struct optional
typedef Predicate predicate;
};
template <class Tag, class Predicate>
struct unnamed
template <class Tag>
struct deduced
{
typedef Tag key_type;
typedef Predicate predicate;
};
namespace aux
{
// Defines metafunctions, is_required and is_optional, that
// identify required<...>, optional<...> and unnamed<...> specializations.
// identify required<...>, optional<...> and deduced<...> specializations.
BOOST_DETAIL_IS_XXX_DEF(required, required, 2)
BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2)
BOOST_DETAIL_IS_XXX_DEF(unnamed, unnamed, 2)
BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1)
template <class S>
struct is_deduced0
: is_deduced_aux<
typename S::key_type
>::type
{};
template <class S>
struct is_deduced
: mpl::eval_if<
mpl::or_<
is_optional<S>, is_required<S>
>
, is_deduced0<S>
, mpl::false_
>::type
{};
//
// key_type, has_default, and predicate --
@@ -108,27 +139,36 @@ namespace aux
// argument type is required match.
//
// a ParameterSpec is a specialization of either keyword<...>,
// required<...>, optional<...> or unnamed<...>
// required<...>, optional<...>
//
// helper for key_type<...>, below.
template <class T>
struct get_key_type
{ typedef typename T::key_type type; };
struct get_tag_type0
{
typedef typename T::key_type type;
};
template <class T>
struct key_type
struct get_tag_type
: mpl::eval_if<
is_deduced_aux<typename T::key_type>
, get_tag_type0<typename T::key_type>
, mpl::identity<typename T::key_type>
>
{};
template <class T>
struct tag_type
: mpl::eval_if<
mpl::or_<
is_optional<T>
, is_required<T>
, is_unnamed<T>
>
, get_key_type<T>
, get_tag_type<T>
, mpl::identity<T>
>
{
};
{};
template <class T>
struct has_default
@@ -163,7 +203,6 @@ namespace aux
mpl::or_<
is_optional<T>
, is_required<T>
, is_unnamed<T>
>
, get_predicate<T>
, mpl::identity<mpl::always<mpl::true_> >
@@ -174,13 +213,13 @@ namespace aux
// Converts a ParameterSpec into a specialization of
// parameter_requirements. We need to do this in order to get the
// key_type into the type in a way that can be conveniently matched
// tag_type into the type in a way that can be conveniently matched
// by a satisfies(...) member function in arg_list.
template <class ParameterSpec>
struct as_parameter_requirements
{
typedef parameter_requirements<
typename key_type<ParameterSpec>::type
typename tag_type<ParameterSpec>::type
, typename predicate<ParameterSpec>::type
, typename has_default<ParameterSpec>::type
> type;
@@ -194,27 +233,6 @@ namespace aux
>
{};
// Labels Arg with default keyword tag DefaultTag if it is not
// already a tagged_argument. If an unnamed spec that matches
// Arg exists in UnnamedList, labels Arg with that spec's
// keyword tag.
template <class Positional, class Arg, class UnnamedList, class TagFn>
struct as_tagged_argument
: mpl::eval_if<
is_named_argument<Arg>
, mpl::identity<mpl::pair<Arg, UnnamedList> >
, mpl::apply_wrap3<UnnamedList, Arg, Positional, TagFn>
>
{};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
template <>
struct as_tagged_argument<int,int,int,int>
{
typedef int type;
};
#endif
// Returns mpl::true_ iff the given ParameterRequirements are
// satisfied by ArgList.
template <class ArgList, class ParameterRequirements>
@@ -223,18 +241,22 @@ namespace aux
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
// VC7.1 can't handle the sizeof() implementation below,
// so we use this instead.
typedef typename mpl::apply_wrap2<
typedef typename mpl::apply_wrap3<
typename ArgList::binding
, typename ParameterRequirements::keyword
, void_
, mpl::false_
>::type bound;
typedef typename mpl::eval_if<
is_same<bound, void_>
, typename ParameterRequirements::has_default
, mpl::apply1<
typename ParameterRequirements::predicate
, typename remove_reference<bound>::type
, mpl::apply_wrap2<
typename mpl::lambda<
typename ParameterRequirements::predicate, lambda_tag
>::type
, bound
, ArgList
>
>::type type;
#else
@@ -242,7 +264,7 @@ namespace aux
bool, value = (
sizeof(
aux::to_yesno(
ArgList::satisfies((ParameterRequirements*)0)
ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0)
)
) == sizeof(yes_tag)
)
@@ -262,52 +284,367 @@ namespace aux
>
{};
// Helper for make_partial_arg_list, below. Produce an arg_list
// node for the given ParameterSpec and ArgumentType, whose tail is
// determined by invoking the nullary metafunction TailFn.
template <class ParameterSpec, class ArgumentType, class TagFn, class TailFn>
struct make_arg_list
// Tags a deduced argument Arg with the keyword tag of Spec using TagFn.
// Returns the tagged argument and the mpl::set<> UsedArgs with the
// tag of Spec inserted.
template <class UsedArgs, class Spec, class Arg, class TagFn>
struct tag_deduced
{
template <class UnnamedList>
struct apply
{
typedef typename as_tagged_argument<
ParameterSpec,ArgumentType,UnnamedList,TagFn
>::type tagged_result;
typedef arg_list<
typename mpl::first<tagged_result>::type
, typename mpl::apply_wrap1<
TailFn, typename mpl::second<tagged_result>::type
>::type
> type;
};
typedef mpl::pair<
typename mpl::apply_wrap2<TagFn, typename tag_type<Spec>::type, Arg>::type
, typename aux::insert_<UsedArgs, typename tag_type<Spec>::type>::type
> type;
};
// Just like make_arg_list, except if ArgumentType is void_, the
// result is empty_arg_list. Used to build arg_lists whose length
// depends on the number of non-default (void_) arguments passed to
// a class template.
template <
class ParameterSpec
, class ArgumentType
class Argument
, class ArgumentPack
, class DeducedArgs
, class UsedArgs
, class TagFn
, class TailFn
>
struct make_partial_arg_list
struct deduce_tag;
// Tag type passed to MPL lambda.
struct lambda_tag;
// Helper for deduce_tag<> below.
template <
class Argument
, class ArgumentPack
, class DeducedArgs
, class UsedArgs
, class TagFn
>
struct deduce_tag0
{
template <class UnnamedList>
struct apply
{
typedef typename mpl::eval_if<
is_same<ArgumentType, void_>
, mpl::identity<empty_arg_list>
, mpl::apply_wrap1<
make_arg_list<ParameterSpec, ArgumentType, TagFn, TailFn>
, UnnamedList
>
>::type type;
};
typedef typename DeducedArgs::spec spec;
typedef typename mpl::apply_wrap2<
typename mpl::lambda<
typename spec::predicate, lambda_tag
>::type
, Argument
, ArgumentPack
>::type condition;
// Deduced parameter matches several arguments.
BOOST_MPL_ASSERT((
mpl::not_<mpl::and_<
condition
, aux::has_key_<UsedArgs, typename tag_type<spec>::type>
> >
));
typedef typename mpl::eval_if<
condition
, tag_deduced<UsedArgs, spec, Argument, TagFn>
, deduce_tag<Argument, ArgumentPack, typename DeducedArgs::tail, UsedArgs, TagFn>
>::type type;
};
// Tries to deduced a keyword tag for a given Argument.
// Returns an mpl::pair<> consisting of the tagged_argument<>,
// and an mpl::set<> where the new tag has been inserted.
//
// Argument: The argument type to be tagged.
//
// ArgumentPack: The ArgumentPack built so far.
//
// DeducedArgs: A specialization of deduced_item<> (see below).
// A list containing only the deduced ParameterSpecs.
//
// UsedArgs: An mpl::set<> containing the keyword tags used so far.
//
// TagFn: A metafunction class used to tag positional or deduced
// arguments with a keyword tag.
template <
class Argument
, class ArgumentPack
, class DeducedArgs
, class UsedArgs
, class TagFn
>
struct deduce_tag
{
typedef typename mpl::eval_if<
is_same<DeducedArgs, void_>
, mpl::pair<void_, UsedArgs>
, deduce_tag0<Argument, ArgumentPack, DeducedArgs, UsedArgs, TagFn>
>::type type;
};
template <
class List
, class DeducedArgs
, class TagFn
, class Positional
, class UsedArgs
, class ArgumentPack
, class Error
>
struct make_arg_list_aux;
// Inserts Tagged::key_type into the UserArgs set.
// Extra indirection to lazily evaluate Tagged::key_type.
template <class UsedArgs, class Tagged>
struct insert_tagged
{
typedef typename aux::insert_<
UsedArgs, typename Tagged::key_type
>::type type;
};
// Borland needs the insane extra-indirection workaround below
// so that it doesn't magically drop the const qualifier from
// the argument type.
template <
class List
, class DeducedArgs
, class TagFn
, class Positional
, class UsedArgs
, class ArgumentPack
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, class argument
#endif
, class Error
>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
struct make_arg_list00
#else
struct make_arg_list0
#endif
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename List::arg argument;
#endif
typedef typename List::spec parameter_spec;
typedef typename tag_type<parameter_spec>::type tag_;
typedef is_named_argument<argument> is_tagged;
// If this argument is either explicitly tagged or a deduced
// parameter, we turn off positional matching.
typedef mpl::and_<
mpl::not_<
mpl::or_<is_deduced<parameter_spec>, is_tagged>
>
, Positional
> positional;
// If this parameter is explicitly tagged we add it to the
// used-parmeters set. We only really need to add parameters
// that are deduced, but we would need a way to check if
// a given tag corresponds to a deduced parameter spec.
typedef typename mpl::eval_if<
is_tagged
, insert_tagged<UsedArgs, argument>
, mpl::identity<UsedArgs>
>::type used_args;
// If this parameter is neither explicitly tagged, nor
// positionally matched; deduce the tag from the deduced
// parameter specs.
typedef typename mpl::eval_if<
mpl::or_<is_tagged, positional>
, mpl::pair<void_, used_args>
, deduce_tag<argument, ArgumentPack, DeducedArgs, used_args, TagFn>
>::type deduced_data;
// If this parameter is explicitly tagged..
typedef typename mpl::eval_if<
is_tagged
, mpl::identity<argument> // .. just use it
, mpl::eval_if< // .. else, if positional matching is turned on..
positional
, mpl::apply_wrap2<TagFn, tag_, argument> // .. tag it positionally
, mpl::first<deduced_data> // .. else, use the deduced tag
>
>::type tagged;
// We build the arg_list incrementally as we go, prepending new
// nodes.
typedef typename mpl::if_<
mpl::and_<
is_same<Error, void_>
, is_same<tagged, void_>
>
, parameter_::unmatched_argument<argument>
, void_
>::type error;
typedef typename mpl::if_<
is_same<tagged, void_>
, ArgumentPack
, arg_list<tagged, ArgumentPack>
>::type argument_pack;
typedef typename make_arg_list_aux<
typename List::tail
, DeducedArgs
, TagFn
, positional
, typename deduced_data::second
, argument_pack
, error
>::type type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <
class List
, class DeducedArgs
, class TagFn
, class Positional
, class UsedArgs
, class ArgumentPack
, class Error
>
struct make_arg_list0
{
typedef typename mpl::eval_if<
typename List::is_arg_const
, make_arg_list00<
List
, DeducedArgs
, TagFn
, Positional
, UsedArgs
, ArgumentPack
, typename List::arg const
, Error
>
, make_arg_list00<
List
, DeducedArgs
, TagFn
, Positional
, UsedArgs
, ArgumentPack
, typename List::arg
, Error
>
>::type type;
};
#endif
// Returns an ArgumentPack where the list of arguments has
// been tagged with keyword tags.
//
// List: A specialization of item<> (see below). Contains
// both the ordered ParameterSpecs, and the given arguments.
//
// DeducedArgs: A specialization of deduced_item<> (see below).
// A list containing only the deduced ParameterSpecs.
//
// TagFn: A metafunction class used to tag positional or deduced
// arguments with a keyword tag.
//
// Position: An mpl::bool_<> specialization indicating if positional
// matching is to be performed.
//
// DeducedSet: An mpl::set<> containing the keyword tags used so far.
//
// ArgumentPack: The ArgumentPack built so far. This is initially an
// empty_arg_list and is built incrementally.
//
template <
class List
, class DeducedArgs
, class TagFn
, class Positional
, class DeducedSet
, class ArgumentPack
, class Error
>
struct make_arg_list_aux
{
typedef typename mpl::eval_if<
is_same<List, void_>
, mpl::identity<mpl::pair<ArgumentPack, Error> >
, make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error>
>::type type;
};
// VC6.5 was choking on the default parameters for make_arg_list_aux, so
// this just forwards to that adding in the defaults.
template <
class List
, class DeducedArgs
, class TagFn
, class EmitErrors = mpl::true_
>
struct make_arg_list
{
typedef typename make_arg_list_aux<
List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_
>::type type;
};
// A parameter spec item typelist.
template <class Spec, class Arg, class Tail = void_>
struct item
{
typedef Spec spec;
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef is_const<Arg> is_arg_const;
#endif
typedef Arg arg;
typedef Tail tail;
};
template <class Spec, class Arg, class Tail>
struct make_item
{
typedef item<Spec, Arg, typename Tail::type> type;
};
// Creates a item typelist.
template <class Spec, class Arg, class Tail>
struct make_items
{
typedef typename mpl::eval_if<
is_same<Arg, void_>
, mpl::identity<void_>
, make_item<Spec, Arg, Tail>
>::type type;
};
// A typelist that stored deduced parameter specs.
template <class ParameterSpec, class Tail = void_>
struct deduced_item
{
typedef ParameterSpec spec;
typedef Tail tail;
};
// Evaluate Tail and construct deduced_item list.
template <class Spec, class Tail>
struct make_deduced_item
{
typedef deduced_item<Spec, typename Tail::type> type;
};
template <class Spec, class Tail>
struct make_deduced_items
{
typedef typename mpl::eval_if<
is_same<Spec, void_>
, mpl::identity<void_>
, mpl::eval_if<
is_deduced<Spec>
, make_deduced_item<Spec, Tail>
, Tail
>
>::type type;
};
// Generates:
@@ -322,124 +659,24 @@ namespace aux
#define BOOST_PARAMETER_make_arg_list(z, n, names) \
BOOST_PP_SEQ_ELEM(0,names)< \
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), \
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), \
BOOST_PP_SEQ_ELEM(3,names),
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n),
#define BOOST_PARAMETER_right_angle(z, n, text) >
#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type, tag) \
#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \
BOOST_PP_REPEAT( \
n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)(tag)) \
mpl::always<aux::empty_arg_list> \
n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \
mpl::identity<void_> \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
// Terminates an unnamed_list (below).
struct empty_unnamed_list
{
template <class Arg, class Positional, class TagFn>
struct apply
{
// No unnamed predicate matched Arg, so we tag Arg with
// the DefaultTag.
BOOST_MPL_ASSERT_NOT((is_unnamed<Positional>));
typedef mpl::pair<
typename mpl::apply_wrap2<
TagFn
, typename key_type<Positional>::type
, Arg
>::type
, empty_unnamed_list
> type;
};
};
// Used by as_tagged_argument to match a given
// argument with a list of unnamed specs.
//
// ParameterSpec is an unnamed spec.
// Tail is either another unnamed_list specialization,
// or empty_unnamed_list.
template <class ParameterSpec, class Tail>
struct unnamed_list
{
// Helper metafunction for apply below. Computes the result
// of Tail::apply. Returns a pair consisting of:
//
// * the tagged argument
// * the unnamed_list that is left after the tagging. Possibly
// with one element removed.
template <class Arg, class Positional, class TagFn>
struct eval_tail
{
typedef typename mpl::apply_wrap3<
Tail, Arg, Positional, TagFn
>::type result;
typedef mpl::pair<
typename mpl::first<result>::type
, unnamed_list<ParameterSpec, typename mpl::second<result>::type>
> type;
};
// If this keyword's predicate returns true for
// the given argument type, tag the argument with
// ParameterSpec::key_type. Otherwise try the tail.
template <class Arg, class Positional, class TagFn>
struct apply
{
typedef typename mpl::eval_if<
typename mpl::apply1<typename ParameterSpec::predicate, Arg>::type
, mpl::pair<
typename mpl::apply_wrap2<
TagFn, typename ParameterSpec::key_type, Arg
>::type
, Tail
>
,
#if BOOST_WORKAROUND(__GNUC__, < 3)
typename unnamed_list<ParameterSpec, Tail>::template
#endif
eval_tail<Arg, Positional, TagFn>
>::type type;
};
};
// We need to build a list of all ParameterSpec's that specify an
// unnamed argument. This list is used when trying to match an
// argument to an unnamed keyword.
template <class ParameterSpec, class TailFn>
struct make_unnamed_list
{
typedef unnamed_list<
ParameterSpec
, typename TailFn::type
> type;
};
template <class ParameterSpec, class TailFn>
struct make_partial_unnamed_list
: mpl::eval_if<
is_same<ParameterSpec, void_>
, mpl::identity<empty_unnamed_list>
, mpl::eval_if<
is_unnamed<ParameterSpec>
, make_unnamed_list<ParameterSpec, TailFn>
, TailFn
>
>
{};
#define BOOST_PARAMETER_make_unnamed_list(z, n, names) \
#define BOOST_PARAMETER_make_deduced_list(z, n, names) \
BOOST_PP_SEQ_ELEM(0,names)< \
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),
#define BOOST_PARAMETER_build_unnamed_list(n, make, parameter_spec) \
#define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec) \
BOOST_PP_REPEAT( \
n, BOOST_PARAMETER_make_unnamed_list, (make)(parameter_spec)) \
mpl::identity<aux::empty_unnamed_list> \
n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec)) \
mpl::identity<void_> \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
struct tag_keyword_arg
@@ -461,6 +698,13 @@ namespace aux
} // namespace aux
#define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \
typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i);
#define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest))
#define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_
template<
@@ -471,9 +715,9 @@ struct parameters
{
#undef BOOST_PARAMETER_TEMPLATE_ARGS
typedef typename BOOST_PARAMETER_build_unnamed_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_unnamed_list, PS
)::type unnamed_list;
typedef typename BOOST_PARAMETER_build_deduced_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS
)::type deduced_list;
// if the elements of NamedList match the criteria of overload
// resolution, returns a type which can be constructed from
@@ -485,7 +729,7 @@ struct parameters
// If NamedList satisfies the PS0, PS1, ..., this is a
// metafunction returning parameters. Otherwise it
// has no nested ::type.
template <class NamedList>
template <class ArgumentPackAndError>
struct match_base
: mpl::if_<
// mpl::and_<
@@ -495,13 +739,18 @@ struct parameters
// ..., mpl::true_
// ...> >
# define BOOST_PARAMETER_satisfies(z, n, text) \
# define BOOST_PARAMETER_satisfies(z, n, text) \
mpl::and_< \
aux::satisfies_requirements_of<NamedList, BOOST_PP_CAT(PS, n)> ,
BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
mpl::true_
BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
aux::satisfies_requirements_of< \
typename mpl::first<ArgumentPackAndError>::type \
, BOOST_PP_CAT(PS, n)> \
,
mpl::and_<
is_same<typename mpl::second<ArgumentPackAndError>::type, void_>
, BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
mpl::true_
BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
>
# undef BOOST_PARAMETER_satisfies
@@ -523,15 +772,19 @@ struct parameters
BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
)
#endif
#endif
>
struct match
# ifndef BOOST_NO_SFINAE
: match_base<
typename mpl::apply_wrap1<BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A
typename aux::make_arg_list<
typename BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
)::type
, deduced_list
, aux::tag_keyword_arg
), unnamed_list>::type
, mpl::false_ // Don't emit errors when doing SFINAE
>::type
>::type
{};
# else
@@ -543,7 +796,10 @@ struct parameters
# endif
// Metafunction that returns an ArgumentPack.
// TODO, bind has to instantiate the error type in the result
// of make_arg_list.
template <
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland simply can't handle default arguments in member
@@ -558,54 +814,58 @@ struct parameters
>
struct bind
{
typedef typename mpl::apply_wrap1<BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A
typedef typename aux::make_arg_list<
typename BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
)::type
, deduced_list
, aux::tag_template_keyword_arg
), unnamed_list>::type type;
>::type result;
typedef typename mpl::first<result>::type type;
};
// Metafunction that returns an ArgumentPack.
template <
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland simply can't handle default arguments in member
// class templates. People wishing to write portable code can
// explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
#else
BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
)
#endif
>
struct argument_pack
{
typedef typename mpl::apply_wrap1<BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A
, aux::tag_keyword_arg
), unnamed_list>::type type;
};
BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec)
//
// The function call operator is used to build an arg_list that
// labels the positional parameters and maintains whatever other
// tags may have been specified by the caller.
//
// !!!NOTE!!!
//
// The make_arg_list<> produces a reversed arg_list, so
// we need to pass the arguments to it's constructor
// reversed.
//
aux::empty_arg_list operator()() const
{
return aux::empty_arg_list();
}
template<class A0>
typename mpl::apply_wrap1<
aux::make_arg_list<PS0,A0, aux::tag_keyword_arg, mpl::always<aux::empty_arg_list> >
, unnamed_list
typename mpl::first<
typename aux::make_arg_list<
aux::item<
PS0,A0
>
, deduced_list
, aux::tag_keyword_arg
>::type
>::type
operator()(A0& a0) const
{
typedef typename mpl::apply_wrap1<
aux::make_arg_list<PS0,A0,aux::tag_keyword_arg,mpl::always<aux::empty_arg_list> >
, unnamed_list
>::type result_type;
typedef typename aux::make_arg_list<
aux::item<
PS0,A0
>
, deduced_list
, aux::tag_keyword_arg
>::type result;
typedef typename mpl::first<result>::type result_type;
typedef typename mpl::second<result>::type error;
error();
return result_type(
a0
@@ -617,31 +877,37 @@ struct parameters
}
template<class A0, class A1>
typename mpl::apply_wrap1<
aux::make_arg_list<
PS0,A0,aux::tag_keyword_arg
, aux::make_arg_list<
PS1,A1,aux::tag_keyword_arg
, mpl::always<aux::empty_arg_list>
typename mpl::first<
typename aux::make_arg_list<
aux::item<
PS0,A0
, aux::item<
PS1,A1
>
>
>
, unnamed_list
, deduced_list
, aux::tag_keyword_arg
>::type
>::type
operator()(A0& a0, A1& a1) const
{
typedef typename mpl::apply_wrap1<
aux::make_arg_list<
PS0,A0,aux::tag_keyword_arg
, aux::make_arg_list<
PS1,A1,aux::tag_keyword_arg
, mpl::always<aux::empty_arg_list>
typedef typename aux::make_arg_list<
aux::item<
PS0,A0
, aux::item<
PS1,A1
>
>
, unnamed_list
>::type result_type;
, deduced_list
, aux::tag_keyword_arg
>::type result;
typedef typename mpl::first<result>::type result_type;
typedef typename mpl::second<result>::type error;
error();
return result_type(
a0, a1
a1,a0
// , void_(), void_() ...
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
@@ -654,10 +920,6 @@ struct parameters
3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \
))
#include BOOST_PP_ITERATE()
#undef BOOST_PARAMETER_build_arg_list
#undef BOOST_PARAMETER_make_arg_list
#undef BOOST_PARAMETER_right_angle
};

File diff suppressed because it is too large Load Diff

View File

@@ -22,8 +22,10 @@
# include <boost/mpl/next.hpp>
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/empty.hpp>
# include <boost/python/def.hpp>
# include <boost/python/make_constructor.hpp>
# include <boost/python/init.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/parameter/aux_/maybe.hpp>
# include <boost/parameter/aux_/python/invoker.hpp>
@@ -323,7 +325,29 @@ namespace aux
Def, Specs*, End, End, Invoker*)
{}
template <class Class, class Options = int>
struct not_specified {};
template <class CallPolicies>
struct call_policies_as_options
{
call_policies_as_options(CallPolicies const& call_policies)
: call_policies(call_policies)
{}
CallPolicies const& policies() const
{
return call_policies;
}
char const* doc() const
{
return 0;
}
CallPolicies call_policies;
};
template <class Class, class Options = not_specified>
struct def_class
{
def_class(Class& cl, char const* name, Options options = Options())
@@ -333,7 +357,7 @@ namespace aux
{}
template <class F>
void def(F f, int const*) const
void def(F f, not_specified const*) const
{
cl.def(name, f);
}
@@ -351,7 +375,7 @@ namespace aux
}
template <class F, class Keywords>
void def(F f, Keywords const& keywords, int const*) const
void def(F f, Keywords const& keywords, not_specified const*) const
{
cl.def(name, f, keywords);
}
@@ -373,11 +397,12 @@ namespace aux
Options options;
};
template <class Class>
template <class Class, class CallPolicies = boost::python::default_call_policies>
struct def_init
{
def_init(Class& cl)
def_init(Class& cl, CallPolicies call_policies = CallPolicies())
: cl(cl)
, call_policies(call_policies)
{}
template <class F>
@@ -385,7 +410,7 @@ namespace aux
{
cl.def(
"__init__"
, boost::python::make_constructor(f)
, boost::python::make_constructor(f, call_policies)
);
}
@@ -394,13 +419,12 @@ namespace aux
{
cl.def(
"__init__"
, boost::python::make_constructor(
f, boost::python::default_call_policies(), keywords
)
, boost::python::make_constructor(f, call_policies, keywords)
);
}
Class& cl;
CallPolicies call_policies;
};
struct def_function
@@ -440,6 +464,7 @@ void def(char const* name, Signature)
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
@@ -473,6 +498,7 @@ void def(Class& cl, char const* name, Signature)
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
@@ -503,8 +529,15 @@ namespace aux
template <class K>
struct keyword<K*>
: keyword<K>
{};
{
typedef K type;
};
template <class K>
struct keyword<K**>
{
typedef K type;
};
template <class K>
struct required
@@ -529,114 +562,159 @@ namespace aux
{
typedef mpl::false_ type;
};
template <class T>
struct make_kw_spec;
template <class K, class T>
struct make_kw_spec
struct make_kw_spec<K(T)>
{
typedef arg_spec<
typename keyword<K>::type
, typename required<K>::type
, typename optimized<K>::type
, T
> type;
> type;
};
} // namespace aux
template <class Keywords, class Signature>
template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
struct init
: boost::python::def_visitor<init<Keywords, Signature> >
: boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
{
init(CallPolicies call_policies = CallPolicies())
: call_policies(call_policies)
{}
template <class CallPolicies1>
init<ParameterSpecs, CallPolicies1>
operator[](CallPolicies1 const& call_policies) const
{
return init<ParameterSpecs, CallPolicies1>(call_policies);
}
template <class Class>
void visit(Class& cl) const
void visit_aux(Class& cl, mpl::true_) const
{
cl.def(boost::python::init<>()[call_policies]);
}
template <class Class>
void visit_aux(Class& cl, mpl::false_) const
{
typedef typename mpl::transform<
Keywords
, Signature
, aux::make_kw_spec<mpl::_1, mpl::_2>
ParameterSpecs
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
, aux::is_optional<mpl::_>
>::type optional_arity;
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
aux::def_combinations(
aux::def_init<Class>(cl)
aux::def_init<Class, CallPolicies>(cl, call_policies)
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_init_invoker<typename Class::wrapped_type>*)0
);
}
template <class Class>
void visit(Class& cl) const
{
visit_aux(cl, mpl::empty<ParameterSpecs>());
}
CallPolicies call_policies;
};
template <class Keywords, class Signature>
template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
struct call
: boost::python::def_visitor<call<Keywords, Signature> >
: boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
{
call(CallPolicies const& call_policies = CallPolicies())
: call_policies(call_policies)
{}
template <class CallPolicies1>
call<ParameterSpecs, CallPolicies1>
operator[](CallPolicies1 const& call_policies) const
{
return call<ParameterSpecs, CallPolicies1>(call_policies);
}
template <class Class>
void visit(Class& cl) const
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<Signature>::type
typename mpl::begin<ParameterSpecs>::type
>::type
, typename mpl::end<Signature>::type
, typename mpl::end<ParameterSpecs>::type
> arg_types;
typedef typename mpl::front<ParameterSpecs>::type result_type;
typedef typename mpl::transform<
Keywords
, arg_types
, aux::make_kw_spec<mpl::_1, mpl::_2>
arg_types
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
, aux::is_optional<mpl::_>
>::type optional_arity;
typedef typename mpl::front<Signature>::type result_type;
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
typedef aux::call_policies_as_options<CallPolicies> options;
aux::def_combinations(
aux::def_class<Class>(cl, "__call__")
aux::def_class<Class, options>(cl, "__call__", options(call_policies))
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
);
}
CallPolicies call_policies;
};
template <class Fwd, class Keywords, class Signature>
template <class Fwd, class ParameterSpecs>
struct function
: boost::python::def_visitor<function<Fwd, Keywords, Signature> >
: boost::python::def_visitor<function<Fwd, ParameterSpecs> >
{
template <class Class, class Options>
void visit(Class& cl, char const* name, Options const& options) const
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<Signature>::type
typename mpl::begin<ParameterSpecs>::type
>::type
, typename mpl::end<Signature>::type
, typename mpl::end<ParameterSpecs>::type
> arg_types;
typedef typename mpl::front<ParameterSpecs>::type result_type;
typedef typename mpl::transform<
Keywords
, arg_types
, aux::make_kw_spec<mpl::_1, mpl::_2>
arg_types
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
, aux::is_optional<mpl::_>
>::type optional_arity;
typedef typename mpl::front<Signature>::type result_type;
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
aux::def_combinations(

View File

@@ -0,0 +1,108 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#ifndef BOOST_PARAMETER_VALUE_TYPE_060921_HPP
# define BOOST_PARAMETER_VALUE_TYPE_060921_HPP
# include <boost/mpl/apply.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/and.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/mpl/eval_if.hpp>
# endif
namespace boost { namespace parameter {
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns Default
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct value_type0
{
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::false_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
};
# endif
template <class Parameters, class Keyword, class Default = void_>
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct value_type
# else
struct value_type_eti
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
, value_type0<Parameters,Keyword,Default>
>::type type;
# else
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::false_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
# endif
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class Parameters, class Keyword, class Default = void_>
struct value_type
{
typedef typename mpl::eval_if<
is_same<Parameters, int>
, mpl::identity<int>
, value_type_eti<Parameters, Keyword, Default>
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
};
# endif
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns the type returned by invoking
// DefaultFn
template <class Parameters, class Keyword, class DefaultFn>
struct lazy_value_type
{
typedef typename mpl::apply_wrap3<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
, mpl::false_
>::type type;
};
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_VALUE_TYPE_060921_HPP

View File

@@ -1,38 +0,0 @@
# Boost Parameter Library test Jamfile
subproject libs/parameter/test ;
# bring in rules for testing
import testing ;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run unnamed.cpp ]
[ run earwicker.cpp ]
[ run tutorial.cpp ]
[ run singular.cpp ]
[ run mpl.cpp ]
[ run preprocessor.cpp ]
[ run efficiency.cpp : : : : : release ]
[ run maybe.cpp ]
[ compile ntp.cpp ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
[ compile-fail unnamed_fail.cpp ]
[ compile compose.cpp ]
;
import python ;
extension python_parameter
: python.cpp
<template>@boost/libs/python/build/extension
;
boost-python-runtest python-parameter-test
: python.py
<pyd>python_parameter
;

View File

@@ -1,5 +1,11 @@
# Copyright David Abrahams, Daniel Wallin 2006. 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)
# Boost Parameter Library test Jamfile
import python ;
project boost/parameter
: default-build <warnings>off
;
@@ -8,18 +14,23 @@ test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run unnamed.cpp ]
[ run earwicker.cpp ]
[ run tutorial.cpp ]
[ run singular.cpp ]
[ run mpl.cpp ]
[ run preprocessor.cpp ]
[ run preprocessor_deduced.cpp ]
[ run efficiency.cpp : : : : : <variant>release ]
[ run maybe.cpp ]
[ run deduced.cpp ]
[ run optional_deduced_sfinae.cpp ]
[ run deduced_dependent_predicate.cpp ]
[ run normalized_argument_types.cpp ]
[ compile ntp.cpp ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
[ compile-fail unnamed_fail.cpp ]
[ compile-fail deduced_unmatched_arg.cpp ]
[ compile compose.cpp ]
[ bpl-test python_test ]
;

View File

@@ -11,7 +11,6 @@
#include "basics.hpp"
namespace test
{
// A separate function for getting the "value" key, so we can deduce

114
test/deduced.cpp Executable file
View File

@@ -0,0 +1,114 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#include "deduced.hpp"
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)
int main()
{
using namespace parameter;
check<
parameters<
tag::x
, tag::y
>
>(
(_x = 0, _y = 1)
, 0
, 1
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = not_present, _z = "foo")
, _x = 0
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, "foo"
, 1
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, 1
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, _y = 1
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, _z = "foo"
, _x = 0
, 1
);
// Fails becasue of parameters.hpp:428
/*
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, _x = 0
, (long*)0
, 1
);
*/
return 0;
};

77
test/deduced.hpp Executable file
View File

@@ -0,0 +1,77 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#ifndef BOOST_DEDUCED_060920_HPP
# define BOOST_DEDUCED_060920_HPP
# include <boost/mpl/for_each.hpp>
# include "basics.hpp"
struct not_present_tag {};
not_present_tag not_present;
template <class E, class ArgPack>
struct assert_expected
{
assert_expected(E const& e, ArgPack const& args)
: expected(e)
, args(args)
{}
template <class T>
bool check_not_present(T const&) const
{
BOOST_MPL_ASSERT((boost::is_same<T,not_present_tag>));
return true;
}
template <class K>
bool check1(K const& k, not_present_tag const&, long) const
{
return check_not_present(args[k | not_present]);
}
template <class K, class Expected>
bool check1(K const& k, Expected const& expected, int) const
{
return test::equal(args[k], expected);
}
template <class K>
void operator()(K) const
{
boost::parameter::keyword<K> const& k = boost::parameter::keyword<K>::get();
assert(check1(k, expected[k], 0L));
}
E const& expected;
ArgPack const& args;
};
template <class E, class ArgPack>
void check0(E const& e, ArgPack const& args)
{
boost::mpl::for_each<E>(assert_expected<E,ArgPack>(e, args));
}
template <class P, class E, class A0>
void check(E const& e, A0 const& a0)
{
check0(e, P()(a0));
}
template <class P, class E, class A0, class A1>
void check(E const& e, A0 const& a0, A1 const& a1)
{
check0(e, P()(a0,a1));
}
template <class P, class E, class A0, class A1, class A2>
void check(E const& e, A0 const& a0, A1 const& a1, A2 const& a2)
{
check0(e, P()(a0,a1,a2));
}
#endif // BOOST_DEDUCED_060920_HPP

View File

@@ -0,0 +1,109 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/type_traits.hpp>
#include "deduced.hpp"
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)
int main()
{
using namespace parameter;
using boost::is_same;
using boost::remove_reference;
using boost::add_reference;
check<
parameters<
tag::x
, optional<
deduced<tag::y>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, is_same<
mpl::_1
, remove_reference<binding<mpl::_2,tag::x> >
>
#else
, is_same<
add_reference<mpl::_1>
, binding<mpl::_2,tag::x>
>
#endif
>
>
>(
(_x = 0, _y = 1)
, 0
, 1
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, is_same<
mpl::_1
, remove_reference<binding<mpl::_2,tag::x> >
>
#else
, is_same<
add_reference<mpl::_1>
, binding<mpl::_2,tag::x>
>
#endif
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
, is_same<
mpl::_1
, tag::x::_
>
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
, is_same<
mpl::_1
, tag::x::_1
>
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
return 0;
}

25
test/deduced_unmatched_arg.cpp Executable file
View File

@@ -0,0 +1,25 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
int main()
{
using namespace parameter;
using boost::is_convertible;
using mpl::_;
parameters<
optional<
deduced<tag::x>, is_convertible<_,int>
>
>()("foo");
}

View File

@@ -30,5 +30,6 @@ int main()
assert(f(unused = 0) == 1);
assert(f((kw = maybe<int>(), unused = 0)) == 1);
assert(f((kw = maybe<int>(2), unused = 0)) == 2);
return 0;
}

View File

@@ -9,9 +9,7 @@
#include <boost/mpl/size.hpp>
#include <boost/type_traits/add_pointer.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/find.hpp>
# include <boost/mpl/end.hpp>
# include <boost/mpl/contains.hpp>
namespace test
{
@@ -23,13 +21,7 @@ namespace test
template <class T>
void operator()(T*)
{
#if 1 // mpl::set is too unreliable in this release.
typedef typename mpl::find<Set,T>::type pos;
typedef typename mpl::end<Set>::type not_found;
BOOST_MPL_ASSERT_NOT((boost::is_same<pos, not_found>));
#else
BOOST_MPL_ASSERT((mpl::has_key<Set,T>));
#endif
BOOST_MPL_ASSERT((mpl::contains<Set,T>));
}
};
@@ -42,7 +34,7 @@ namespace test
, ==
, mpl::size<Params>::value
);
mpl::for_each<Params, boost::add_pointer<mpl::_1> >(assert_in_set<Expected>());
}

View File

@@ -0,0 +1,85 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <cassert>
struct count_instances
{
count_instances()
{
++count;
}
count_instances(count_instances const&)
{
++count;
}
template <class T>
count_instances(T const&)
{
++count;
}
~count_instances()
{
--count;
}
static std::size_t count;
};
std::size_t count_instances::count = 0;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_FUNCTION((int), f, tag,
(required
(x, (int))
(y, (int))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,int>));
BOOST_MPL_ASSERT((boost::is_same<y_type,int>));
return 0;
}
BOOST_PARAMETER_FUNCTION((int), g, tag,
(required
(x, (count_instances))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances>));
assert(count_instances::count > 0);
return 0;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(x, (count_instances const&))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances const>));
assert(count_instances::count == 1);
return 0;
}
int main()
{
f(1, 2);
f(1., 2.f);
f(1U, 2L);
g(0);
h(0);
}

View File

@@ -43,8 +43,9 @@ struct with_ntp
{
typedef typename parameter::parameters<
a0_is<>, a1_is<>, a2_is<>
, parameter::unnamed<
a3_is<>, boost::is_base_and_derived<X, mpl::_>
, parameter::optional<
parameter::deduced<a3_is<> >
, boost::is_base_and_derived<X, mpl::_>
>
>::bind<A0,A1,A2,A3
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
@@ -100,10 +101,10 @@ BOOST_MPL_ASSERT((boost::is_same<
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<Y>::type, void(*)(void*,void*,void*, Y)
with_ntp<a0_is<int>, Y>::type, void(*)(int,void*,void*, Y)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int&, Y, a2_is<char> >::type, void(*)(int&,void*,char, Y)
with_ntp<int&, a2_is<char>, Y>::type, void(*)(int&,void*,char, Y)
>));

View File

@@ -0,0 +1,73 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/name.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include "basics.hpp"
#include <boost/utility/enable_if.hpp>
namespace test {
namespace mpl = boost::mpl;
using mpl::_;
using boost::is_convertible;
BOOST_PARAMETER_NAME(x)
// Sun has problems with this syntax:
//
// template1< r* ( template2<x> ) >
//
// Workaround: factor template2<x> into a separate typedef
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
typedef is_convertible<_,char const*> predicate;
BOOST_PARAMETER_FUNCTION((int), sfinae, tag,
(deduced
(optional (x, *(predicate), 0))
)
)
{
return 1;
}
#else
BOOST_PARAMETER_FUNCTION((int), sfinae, tag,
(deduced
(optional (x, *(is_convertible<_,char const*>), 0))
)
)
{
return 1;
}
#endif
template<class A0>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
sfinae(A0 const& a0)
{
return 0;
}
} // namespace test
int main()
{
using namespace test;
assert(sfinae() == 1);
assert(sfinae("foo") == 1);
assert(sfinae(1) == 0);
return 0;
}

View File

@@ -14,7 +14,7 @@
namespace test {
BOOST_PARAMETER_FUNCTION((int), f, tag,
BOOST_PARAMETER_BASIC_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
@@ -40,7 +40,7 @@ BOOST_PARAMETER_FUNCTION((int), f, tag,
return 1;
}
BOOST_PARAMETER_FUNCTION((int), g, tag,
BOOST_PARAMETER_BASIC_FUNCTION((int), g, tag,
(required
(tester, *)
(name, *)
@@ -66,6 +66,56 @@ BOOST_PARAMETER_FUNCTION((int), g, tag,
return 1;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(out(index), (int), 2)
)
)
{
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
&& !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_MPL_ASSERT((boost::is_same<index_type, int>));
# endif
tester(
name
, value
, index
);
return 1;
}
BOOST_PARAMETER_FUNCTION((int), h2, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(out(index), (int), (int)value * 2)
)
)
{
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
&& !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_MPL_ASSERT((boost::is_same<index_type, int>));
# endif
tester(
name
, value
, index
);
return 1;
}
struct base
{
template <class Args>
@@ -92,7 +142,7 @@ struct class_ : base
)
)
BOOST_PARAMETER_MEMBER_FUNCTION((int), f, tag,
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
@@ -112,7 +162,7 @@ struct class_ : base
return 1;
}
BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f, tag,
BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
@@ -131,6 +181,52 @@ struct class_ : base
return 1;
}
BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(index, *, 2)
)
)
{
tester(name, value, index);
return 1;
}
BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(index, *, 2)
)
)
{
tester(name, value, index);
return 1;
}
BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(index, *, 2)
)
)
{
tester(name, value, index);
return 1;
}
};
BOOST_PARAMETER_FUNCTION(
@@ -158,14 +254,91 @@ sfinae(A0 const& a0)
}
#endif
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
// Sun has problems with this syntax:
//
// template1< r* ( template2<x> ) >
//
// Workaround: factor template2<x> into a separate typedef
typedef boost::is_convertible<boost::mpl::_, std::string> predicate;
BOOST_PARAMETER_FUNCTION(
(int), sfinae1, tag,
(required
(name, *(predicate))
)
)
{
return 1;
}
#else
BOOST_PARAMETER_FUNCTION(
(int), sfinae1, tag,
(required
(name, *(boost::is_convertible<boost::mpl::_, std::string>))
)
)
{
return 1;
}
#endif
#ifndef BOOST_NO_SFINAE
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
// working. On all other compilers we're just checking that
// everything about SFINAE-enabled code will work, except of course
// the SFINAE.
template<class A0>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
sfinae1(A0 const& a0)
{
return 0;
}
#endif
template <class T>
T const& as_lvalue(T const& x)
{
return x;
}
struct udt
{
udt(int foo, int bar)
: foo(foo)
, bar(bar)
{}
int foo;
int bar;
};
BOOST_PARAMETER_FUNCTION((int), lazy_defaults, tag,
(required
(name, *)
)
(optional
(value, *, name.foo)
(index, *, name.bar)
)
)
{
return 0;
}
} // namespace test
int main()
{
using namespace test;
f(
tester = values(S("foo"), 1.f, 2)
values(S("foo"), 1.f, 2)
, S("foo")
);
@@ -175,28 +348,56 @@ int main()
);
int index_lvalue = 2;
f(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, value = 1.f
, test::index = index_lvalue
);
f(
values(S("foo"), 1.f, 2)
, S("foo")
, 1.f
, index_lvalue
);
g(
values(S("foo"), 1.f, 2)
, S("foo")
, 1.f
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, as_lvalue(2)
#else
, 2
#endif
);
h(
values(S("foo"), 1.f, 2)
, S("foo")
, 1.f
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, as_lvalue(2)
#else
, 2
#endif
);
h2(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, 1.f
, 2
, value = 1.f
);
class_ x(
tester = values(S("foo"), 1.f, 2)
values(S("foo"), 1.f, 2)
, S("foo"), test::index = 2
);
x.f(
tester = values(S("foo"), 1.f, 2)
values(S("foo"), 1.f, 2)
, S("foo")
);
@@ -205,10 +406,20 @@ int main()
, name = S("foo")
);
x.f2(
values(S("foo"), 1.f, 2)
, S("foo")
);
x.f2(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
class_ const& x_const = x;
x_const.f(
tester = values(S("foo"), 1.f, 2)
values(S("foo"), 1.f, 2)
, S("foo")
);
@@ -216,10 +427,56 @@ int main()
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
x_const.f2(
values(S("foo"), 1.f, 2)
, S("foo")
);
x_const.f2(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
x_const.f2(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
class_::f_static(
values(S("foo"), 1.f, 2)
, S("foo")
);
class_::f_static(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
#ifndef BOOST_NO_SFINAE
assert(sfinae("foo") == 1);
assert(sfinae(1) == 0);
# if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
// Sun actually eliminates the desired overload for some reason.
// Disabling this part of the test because SFINAE abilities are
// not the point of this test.
assert(sfinae1("foo") == 1);
# endif
assert(sfinae1(1) == 0);
#endif
lazy_defaults(
name = udt(0,1)
);
lazy_defaults(
name = 0
, value = 1
, test::index = 2
);
return 0;
}

171
test/preprocessor_deduced.cpp Executable file
View File

@@ -0,0 +1,171 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/name.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include "basics.hpp"
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
#endif
namespace test {
namespace mpl = boost::mpl;
using mpl::_;
using boost::is_convertible;
BOOST_PARAMETER_NAME(expected)
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)
// Sun has problems with this syntax:
//
// template1< r* ( template2<x> ) >
//
// Workaround: factor template2<x> into a separate typedef
typedef is_convertible<_, int> predicate1;
typedef is_convertible<_, std::string> predicate2;
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
BOOST_PARAMETER_FUNCTION((int), f, tag,
(required
(expected, *)
)
(deduced
(required
(x, *(predicate1))
(y, *(predicate2))
)
)
)
#else
BOOST_PARAMETER_FUNCTION((int), f, tag,
(required
(expected, *)
)
(deduced
(required
(x, *(is_convertible<_, int>))
(y, *(is_convertible<_, std::string>))
)
)
)
#endif
{
assert(equal(x, boost::tuples::get<0>(expected)));
assert(equal(y, boost::tuples::get<1>(expected)));
return 1;
}
struct X
{
X(int x = -1)
: x(x)
{}
bool operator==(X const& other) const
{
return x == other.x;
}
int x;
};
typedef is_convertible<_, X> predicate3; // SunPro workaround; see above
BOOST_PARAMETER_FUNCTION((int), g, tag,
(required
(expected, *)
)
(deduced
(required
(x, *(is_convertible<_, int>))
(y, *(is_convertible<_, std::string>))
)
(optional
(z, *(predicate3), X())
)
)
)
{
assert(equal(x, boost::tuples::get<0>(expected)));
assert(equal(y, boost::tuples::get<1>(expected)));
assert(equal(z, boost::tuples::get<2>(expected)));
return 1;
}
BOOST_PARAMETER_FUNCTION(
(int), sfinae, tag,
(deduced
(required
(x, *(predicate2))
)
)
)
{
return 1;
}
#ifndef BOOST_NO_SFINAE
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
// working. On all other compilers we're just checking that
// everything about SFINAE-enabled code will work, except of course
// the SFINAE.
template<class A0>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
sfinae(A0 const& a0)
{
return 0;
}
#endif
} // namespace test
using boost::make_tuple;
// make_tuple doesn't work with char arrays.
char const* str(char const* s)
{
return s;
}
int main()
{
using namespace test;
f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
f(make_tuple(0, str("foo")), 0, "foo");
f(make_tuple(0, str("foo")), "foo", 0);
f(make_tuple(0, str("foo")), _y = "foo", 0);
f(make_tuple(0, str("foo")), _x = 0, "foo");
f(make_tuple(0, str("foo")), 0, _y = "foo");
g(make_tuple(0, str("foo"), X()), _x = 0, _y = "foo");
g(make_tuple(0, str("foo"), X()), 0, "foo");
g(make_tuple(0, str("foo"), X()), "foo", 0);
g(make_tuple(0, str("foo"), X()), _y = "foo", 0);
g(make_tuple(0, str("foo"), X()), _x = 0, "foo");
g(make_tuple(0, str("foo"), X()), 0, _y = "foo");
g(make_tuple(0, str("foo"), X(1)), 0, _y = "foo", X(1));
g(make_tuple(0, str("foo"), X(1)), X(1), 0, _y = "foo");
#ifndef BOOST_NO_SFINAE
assert(sfinae("foo") == 1);
assert(sfinae(0) == 0);
#endif
return 0;
}

View File

@@ -1,86 +0,0 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
BOOST_PARAMETER_KEYWORD(tag, z)
struct X
{
BOOST_PARAMETER_MEMBER_FUNCTION((int), f, tag,
(required
(x, *)
(y, *)
)
(optional
(z, *)
)
)
{
return args[x] + args[y] + args[z | 0];
}
BOOST_PARAMETER_MEMBER_FUNCTION((std::string), g, tag,
(optional
(x, *)
(y, *)
)
)
{
return std::string(args[x | "foo"]) + args[y | "bar"];
}
};
} // namespace test
struct f_fwd
{
template <class R, class T, class A0, class A1, class A2>
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1, A2 const& a2)
{
return self.f(a0,a1,a2);
}
};
struct g_fwd
{
template <class R, class T, class A0, class A1>
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1)
{
return self.g(a0,a1);
}
};
BOOST_PYTHON_MODULE(python_parameter)
{
namespace mpl = boost::mpl;
using namespace test;
using namespace boost::python;
class_<X>("X")
.def(
"f"
, boost::parameter::python::function<
f_fwd
, mpl::vector3<tag::x, tag::y, tag::z*>
, mpl::vector4<int, int, int, int>
>()
)
.def(
"g"
, boost::parameter::python::function<
g_fwd
, mpl::vector2<tag::x*, tag::y*>
, mpl::vector3<std::string, std::string, std::string>
>()
);
}

View File

@@ -1,31 +0,0 @@
'''
>>> from python_parameter import X
>>> x = X()
>>> x.f(1,2)
3
>>> x.f(1,2,3)
6
>>> x.f(1,2, z = 3)
6
>>> x.f(z = 3, y = 2, x = 1)
6
>>> x.g()
'foobar'
>>> x.g(y = "baz")
'foobaz'
>>> x.g(x = "baz")
'bazbar'
>>> x.g(y = "foo", x = "bar")
'barfoo'
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, python
return doctest.testmod(python)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

171
test/python_test.cpp Executable file
View File

@@ -0,0 +1,171 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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)
#include <boost/python.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/python.hpp>
#include <boost/utility/enable_if.hpp>
namespace test {
BOOST_PARAMETER_KEYWORD(tags, x)
BOOST_PARAMETER_KEYWORD(tags, y)
BOOST_PARAMETER_KEYWORD(tags, z)
struct Xbase
{
// We need the disable_if part for VC7.1/8.0.
template <class Args>
Xbase(
Args const& args
, typename boost::disable_if<
boost::is_base_and_derived<Xbase, Args>
>::type* = 0
)
: value(std::string(args[x | "foo"]) + args[y | "bar"])
{}
std::string value;
};
struct X : Xbase
{
BOOST_PARAMETER_CONSTRUCTOR(X, (Xbase), tags,
(optional
(x, *)
(y, *)
)
)
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tags,
(required
(x, *)
(y, *)
)
(optional
(z, *)
)
)
{
return args[x] + args[y] + args[z | 0];
}
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((std::string), g, tags,
(optional
(x, *)
(y, *)
)
)
{
return std::string(args[x | "foo"]) + args[y | "bar"];
}
BOOST_PARAMETER_MEMBER_FUNCTION((X&), h, tags,
(optional (x, *, "") (y, *, ""))
)
{
return *this;
}
template <class A0>
X& operator()(A0 const& a0)
{
return *this;
}
};
} // namespace test
struct f_fwd
{
template <class R, class T, class A0, class A1, class A2>
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1, A2 const& a2)
{
return self.f(a0,a1,a2);
}
};
struct g_fwd
{
template <class R, class T, class A0, class A1>
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1)
{
return self.g(a0,a1);
}
};
struct h_fwd
{
template <class R, class T>
R operator()(boost::type<R>, T& self)
{
return self.h();
}
template <class R, class T, class A0>
R operator()(boost::type<R>, T& self, A0 const& a0)
{
return self.h(a0);
}
template <class R, class T, class A0, class A1>
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1)
{
return self.h(a0,a1);
}
};
BOOST_PYTHON_MODULE(python_test_ext)
{
namespace mpl = boost::mpl;
using namespace test;
using namespace boost::python;
class_<X>("X")
.def(
boost::parameter::python::init<
mpl::vector<
tags::x*(std::string), tags::y*(std::string)
>
>()
)
.def(
"f"
, boost::parameter::python::function<
f_fwd
, mpl::vector<
int, tags::x(int), tags::y(int), tags::z*(int)
>
>()
)
.def(
"g"
, boost::parameter::python::function<
g_fwd
, mpl::vector<
std::string, tags::x*(std::string), tags::y*(std::string)
>
>()
)
.def(
"h"
, boost::parameter::python::function<
h_fwd
, mpl::vector<
X&, tags::x**(std::string), tags::y**(std::string)
>
>()
, return_arg<>()
)
.def(
boost::parameter::python::call<
mpl::vector<
X&, tags::x(int)
>
>() [ return_arg<>() ]
)
.def_readonly("value", &X::value);
}

41
test/python_test.py Normal file
View File

@@ -0,0 +1,41 @@
# Copyright Daniel Wallin 2006. 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)
'''
>>> from python_test_ext import X
>>> x = X(y = 'baz')
>>> x.value
'foobaz'
>>> x.f(1,2)
3
>>> x.f(1,2,3)
6
>>> x.f(1,2, z = 3)
6
>>> x.f(z = 3, y = 2, x = 1)
6
>>> x.g()
'foobar'
>>> x.g(y = "baz")
'foobaz'
>>> x.g(x = "baz")
'bazbar'
>>> x.g(y = "foo", x = "bar")
'barfoo'
>>> y = x.h(x = "bar", y = "foo")
>>> assert x == y
>>> y = x(0)
>>> assert x == y
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, python_test
return doctest.testmod(python_test)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -5,7 +5,7 @@
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <boost/assert.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
#include <boost/type_traits/is_convertible.hpp>
@@ -38,14 +38,14 @@ namespace test
// vc++ 6 ICE.
void assert_equal_string(std::string x, std::string y)
{
BOOST_ASSERT(x == y);
BOOST_TEST(x == y);
}
template<class P>
void f_impl(P const& p)
{
float v = p[value | 3.f];
BOOST_ASSERT(v == 3.f);
BOOST_TEST(v == 3.f);
assert_equal_string(p[name | "bar"], "foo");
}
@@ -97,9 +97,8 @@ int main()
f(value = 3.f, name = "foo");
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
BOOST_TEST(f(3, 4) == 0);
#endif
return boost::report_errors();
}

View File

@@ -1,75 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to 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)
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <cassert>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <string>
namespace test
{
using namespace boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_KEYWORD(tag, name)
BOOST_PARAMETER_KEYWORD(tag, value)
struct g_parameters
: parameters<
unnamed<tag::name, boost::is_convertible<mpl::_, std::string> >
, unnamed<tag::value, boost::is_convertible<mpl::_, float> >
>
{};
// Keeping this out here avoids an ICE with vc-6.x
std::string const foo("foo");
template<class Params>
int g_(Params const& p)
{
assert(p[name] == foo);
assert(p[value] == 3.14f);
return 1;
}
template<class A0>
int g(A0 const& a0, BOOST_PARAMETER_MATCH(g_parameters, (A0), args))
{
return g_(args(a0));
}
template<class A0, class A1>
int g(A0 const& a0, A1 const& a1, BOOST_PARAMETER_MATCH(g_parameters, (A0)(A1), args))
{
return g_(args(a0, a1));
}
}
#include <typeinfo>
#include <iostream>
int main()
{
using test::g;
using test::name;
using test::value;
g("foo", 3.14f);
g(3.14f, "foo");
g(value = 3.14f, "foo");
g(name = "foo", 3.14f);
g(3.14f, name = "foo");
g(name = "foo", value = 3.14f);
return 0;
}

View File

@@ -1,67 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to 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)
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <cassert>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <string>
namespace test
{
using namespace boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_KEYWORD(tag, name)
BOOST_PARAMETER_KEYWORD(tag, value)
struct g_parameters
: parameters<
unnamed<tag::name, boost::is_convertible<mpl::_, std::string> >
, unnamed<tag::value, boost::is_convertible<mpl::_, float> >
>
{};
// Keeping this out here avoids an ICE with vc-6.x
std::string const foo("foo");
template<class Params>
int g_(Params const& p)
{
return 1;
}
template<class A0>
int g(A0 const& a0, BOOST_PARAMETER_MATCH(g_parameters, (A0), args))
{
return g_(args(a0));
}
template<class A0, class A1>
int g(A0 const& a0, A1 const& a1, BOOST_PARAMETER_MATCH(g_parameters, (A0)(A1), args))
{
return g_(args(a0, a1));
}
}
#include <typeinfo>
#include <iostream>
int main()
{
using test::g;
using test::name;
using test::value;
g("foo", "bar");
return 0;
}