Compare commits

..

19 Commits

Author SHA1 Message Date
Dave Abrahams
8ea9931a55 Every ArgumentPack is now a valid MPL Forward Sequence.
[SVN r32442]
2006-01-27 20:57:33 +00:00
Dave Abrahams
bb4b55b7a7 Every ArgumentPack is now a valid MPL Forward Sequence.
[SVN r32427]
2006-01-27 02:28:26 +00:00
Dave Abrahams
d3affb9173 VC6 workaround
[SVN r32426]
2006-01-27 01:55:17 +00:00
Dave Abrahams
c8dbe27c0d Workarounds for vc6 et al.
[SVN r32425]
2006-01-27 01:25:39 +00:00
Dave Abrahams
0becf3904e Workarounds for Borland and GCC2
[SVN r32420]
2006-01-26 17:00:06 +00:00
Dave Abrahams
ca0899bf88 Workarounds for Borland
[SVN r32410]
2006-01-24 22:35:49 +00:00
Dave Abrahams
01a95f4f5a workaround vc6 ICE
[SVN r32409]
2006-01-24 22:12:13 +00:00
Eric Niebler
3d432ba007 add test_general
[SVN r32318]
2006-01-13 19:05:59 +00:00
Eric Niebler
c637e24175 simple patch to make libs/parameter/test/python/general.cpp compile
[SVN r32315]
2006-01-13 18:41:43 +00:00
Eric Niebler
6a39e83db0 add some python test scripts for simple.cpp and accumulator.cpp
[SVN r32223]
2006-01-04 23:35:53 +00:00
Eric Niebler
76f55205e6 add missing return statements
[SVN r32222]
2006-01-04 23:34:32 +00:00
Daniel Wallin
98f43217b2 Added accumulator sample.
[SVN r32130]
2005-12-22 00:59:40 +00:00
Daniel Wallin
1656f8badd More work on python binding.
[SVN r32129]
2005-12-22 00:58:22 +00:00
Daniel Wallin
5479e72b94 Added runtime determined default's. For use with python wrapping code.
[SVN r32128]
2005-12-22 00:57:53 +00:00
Eric Niebler
914d36970c fix spelling error
[SVN r32110]
2005-12-19 18:21:41 +00:00
Daniel Wallin
e1fce8fbc5 Test for general binding of parameter-enabled functions.
[SVN r31976]
2005-12-10 17:42:26 +00:00
Daniel Wallin
d5378a587a General 2^N case of binding parameter-enabled functions.
[SVN r31975]
2005-12-10 17:40:48 +00:00
Daniel Wallin
9dc905e4c6 Boost.Parameter->BPL initial checkin
[SVN r31843]
2005-11-30 23:18:30 +00:00
nobody
68786750ca This commit was manufactured by cvs2svn to create branch
'parameter-python'.

[SVN r31672]
2005-11-15 20:50:59 +00:00
58 changed files with 5586 additions and 5738 deletions

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,750 +0,0 @@
<?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>
<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>
<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" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">Daniel Wallin</td>
</tr>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><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$</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">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="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="id7" name="id7">Introduction</a></li>
<li><a class="reference" href="#tutorial" id="id8" name="id8">Tutorial</a></li>
<li><a class="reference" href="#concept-keywordsspec" id="id9" name="id9">concept <span class="concept">KeywordsSpec</span></a></li>
<li><a class="reference" href="#special-keywords" id="id10" name="id10"><em>special</em> keywords</a></li>
<li><a class="reference" href="#class-template-init" id="id11" name="id11">class template <tt class="docutils literal"><span class="pre">init</span></tt></a></li>
<li><a class="reference" href="#class-template-call" id="id12" name="id12">class template <tt class="docutils literal"><span class="pre">call</span></tt></a></li>
<li><a class="reference" href="#class-template-function" id="id13" name="id13">class template <tt class="docutils literal"><span class="pre">function</span></tt></a></li>
<li><a class="reference" href="#function-template-def" id="id14" name="id14">function template <tt class="docutils literal"><span class="pre">def</span></tt></a></li>
<li><a class="reference" href="#portability" id="id15" name="id15">Portability</a></li>
</ul>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id7" 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">def_visitors</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>
<p>The keyword tags are specified as an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a>, using the
pointer qualifications described in <a class="reference" href="#concept-keywordsspec"><span class="concept">KeywordsSpec</span></a> below. The
signature is also specifid as an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> of parameter
types. 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="#id8" 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></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">def_visitor</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 three 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 for the function. The
pointer syntax means that the parameter is optional, so in this case
<tt class="docutils literal"><span class="pre">width</span></tt> and <tt class="docutils literal"><span class="pre">height</span></tt> are optional parameters. The third parameter
is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a> with the desired function signature. The return type comes first, and
then the parameter types:</p>
<pre class="literal-block">
mpl::vector&lt;void, std::string, unsigned, unsigned&gt;
<em>return type</em> <em>title</em> <em>width</em> <em>height</em>
</pre>
<!-- @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="#id9" id="concept-keywordsspec" name="concept-keywordsspec">concept <span class="concept">KeywordsSpec</span></a></h1>
<p>A <span class="concept">KeywordsSpec</span> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element is either:</p>
<ul class="simple">
<li>A <em>required</em> keyword of the form <tt class="docutils literal"><span class="pre">K</span></tt></li>
<li><strong>or</strong>, an <em>optional</em> keyword of the form <tt class="docutils literal"><span class="pre">K*</span></tt></li>
<li><strong>or</strong>, a <em>special</em> keyword of the form <tt class="docutils literal"><span class="pre">K**</span></tt></li>
</ul>
<p>where <tt class="docutils literal"><span class="pre">K</span></tt> is a keyword tag type, as used in a specialization
of boost::parameter::<a class="reference" href="../../../parameter/doc/html/reference.html#keyword">keyword</a>.</p>
<p>The <strong>arity range</strong> of a <span class="concept">KeywordsSpec</span> 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>
<!-- @ignore() -->
<p>For example, the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2&lt;x,y&gt;</span></tt> is [2,2], the <strong>arity range</strong> of
<tt class="docutils literal"><span class="pre">mpl::vector2&lt;x,y*&gt;</span></tt> is [2,2] and the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2&lt;x,y**&gt;</span></tt> is [1,2].</p>
<!-- Don't optional keywords affect the arity range? -->
</div>
<div class="section">
<h1><a class="toc-backref" href="#id10" 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 <tt class="docutils literal"><span class="pre">2^N</span></tt>, 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="#id11" 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 Keywords, class Signature&gt;
struct init : python::def_visitor&lt;init&lt;Keywords, Signature&gt; &gt;
{
template &lt;class Class&gt;
void def(Class&amp; class_);
};
</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">Keywords</span></tt> is a model of <span class="concept">KeywordsSpec</span>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">Signature</span></tt> is an MPL sequence of parameter types,
in the order dictated by <tt class="docutils literal"><span class="pre">Keywords</span></tt>.</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">Keywords</span></tt>, <tt class="docutils literal"><span class="pre">Class</span></tt> must support these
expressions:</p>
<table border="1" class="docutils">
<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>
<!-- Limit the width of these table cells. Some rst backend -->
<!-- processors actually produce different results depending on the -->
<!-- distribution of width. -->
</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="#id12" 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 Keywords, class Signature&gt;
struct call : python::def_visitor&lt;call&lt;Keywords, Signature&gt; &gt;
{
template &lt;class Class&gt;
void def(Class&amp; class_);
};
</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">Keywords</span></tt> is a model of <span class="concept">KeywordsSpec</span>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">Signature</span></tt> is an MPL sequence with the types of the keyword parameters,
in the order dictated by <tt class="docutils literal"><span class="pre">Keywords</span></tt>, and the return type prepended.</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">
<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">Keywords</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id4" name="id4">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="#id13" 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 Keywords, class Signature&gt;
struct function : python::def_visitor&lt;function&lt;Fwd, Keywords, Signature&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">Keywords</span></tt> is a model of <span class="concept">KeywordsSpec</span>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">Signature</span></tt> is an MPL sequence with the types of the keyword parameters,
in the order dictated by <tt class="docutils literal"><span class="pre">Keywords</span></tt>, and the return type prepended.</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">
<colgroup>
<col width="40%" />
<col width="18%" />
<col width="42%" />
</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``…``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">Keywords</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id5" name="id5">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 <span class="concept">KeywordsSpec</span> <tt class="docutils literal"><span class="pre">mpl::vector2&lt;tag::x,</span> <span class="pre">tag::y*&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="#id14" 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 Keywords, class Signature&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">Keywords</span></tt> is a model of <span class="concept">KeywordsSpec</span>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">Signature</span></tt> is an MPL sequence of parameters types,
in the order dictated by <tt class="docutils literal"><span class="pre">Keywords</span></tt>, with the return type
prepended.</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">
<colgroup>
<col width="40%" />
<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``…``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">Keywords</span></tt>.</p>
</li>
</ul>
</div>
<div class="section">
<h2><a id="id6" name="id6">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 <span class="concept">KeywordsSpec</span> <tt class="docutils literal"><span class="pre">mpl::vector2&lt;tag::x,</span> <span class="pre">tag::y*&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, <a class="reference" href="tag::x(int">tag::x(int</a>), <a class="reference" href="tag::y*(int">tag::y*(int</a>)
&gt;
&gt;(&quot;f&quot;);
}
</pre>
<!-- @ignore() -->
<!-- again, the undefined ``fwd`` identifier. -->
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id15" 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: 2006-07-26 14:14 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,103 +3,97 @@
<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/" />
<meta name="generator" content="Docutils 0.3.8: 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>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<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" />
<tbody valign="top">
<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
<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
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">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<div class="contents topic" id="contents">
<p class="topic-title first"><a name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#preliminaries" id="id26" name="id26">1&nbsp;&nbsp;&nbsp;Preliminaries</a><ul class="auto-toc">
<li><a class="reference" href="#namespaces" id="id27" name="id27">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></li>
<li><a class="reference" href="#exceptions" id="id28" name="id28">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></li>
<li><a class="reference" href="#thread-safety" id="id29" name="id29">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></li>
<li><a class="reference" href="#typography" id="id30" name="id30">1.4&nbsp;&nbsp;&nbsp;Typography</a></li>
<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>
</ul>
</li>
<li><a class="reference" href="#terminology" id="id31" name="id31">2&nbsp;&nbsp;&nbsp;Terminology</a></li>
<li><a class="reference" href="#concepts" id="id32" name="id32">3&nbsp;&nbsp;&nbsp;Concepts</a><ul class="auto-toc">
<li><a class="reference" href="#argumentpack" id="id33" name="id33">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></li>
<li><a class="reference" href="#id5" id="id34" name="id34">3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></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>
</ul>
</li>
<li><a class="reference" href="#class-templates" id="id35" name="id35">4&nbsp;&nbsp;&nbsp;Class Templates</a><ul class="auto-toc">
<li><a class="reference" href="#id7" id="id36" name="id36">4.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">keyword</span></tt></a></li>
<li><a class="reference" href="#parameters" id="id37" name="id37">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="id38" name="id38">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="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>
</ul>
</li>
<li><a class="reference" href="#metafunctions" id="id39" name="id39">5&nbsp;&nbsp;&nbsp;Metafunctions</a><ul class="auto-toc">
<li><a class="reference" href="#binding" id="id40" name="id40">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="id41" name="id41">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="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>
</ul>
</li>
<li><a class="reference" href="#code-generation-macros" id="id42" name="id42">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="id43" name="id43">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-fun-r-n-l-h-p" id="id44" name="id44">6.2&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="id45" name="id45">6.3&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="id46" name="id46">6.4&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="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>
</ul>
</li>
<li><a class="reference" href="#configuration-macros" id="id47" name="id47">7&nbsp;&nbsp;&nbsp;Configuration Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-max-arity" id="id48" name="id48">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="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>
</ul>
</li>
<li><a class="reference" href="#tutorial" id="id49" name="id49">8&nbsp;&nbsp;&nbsp;Tutorial</a></li>
<li><a class="reference" href="#tutorial" id="id46" name="id46">8&nbsp;&nbsp;&nbsp;Tutorial</a></li>
</ul>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id26" id="preliminaries" name="preliminaries">1&nbsp;&nbsp;&nbsp;Preliminaries</a></h1>
<div class="section" id="preliminaries">
<h1><a class="toc-backref" href="#id24" 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">
<h2><a class="toc-backref" href="#id27" id="namespaces" name="namespaces">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></h2>
<div class="section" id="namespaces">
<h2><a class="toc-backref" href="#id25" 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">
<h2><a class="toc-backref" href="#id28" id="exceptions" name="exceptions">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></h2>
<div class="section" id="exceptions">
<h2><a class="toc-backref" href="#id26" 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">
<h2><a class="toc-backref" href="#id29" id="thread-safety" name="thread-safety">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></h2>
<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>
<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">
<h2><a class="toc-backref" href="#id30" id="typography" name="typography">1.4&nbsp;&nbsp;&nbsp;Typography</a></h2>
<div class="section" id="typography">
<h2><a class="toc-backref" href="#id28" 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
@@ -111,9 +105,9 @@ argument in the result.</p>
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id31" id="terminology" name="terminology">2&nbsp;&nbsp;&nbsp;Terminology</a></h1>
<dl class="docutils" id="kw">
<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">
<dt>keyword</dt>
<dd>The name of a function parameter.</dd>
</dl>
@@ -146,12 +140,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>
@@ -170,16 +164,16 @@ models <a class="reference" href="#argumentpack"><span class="concept">ArgumentP
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id32" id="concepts" name="concepts">3&nbsp;&nbsp;&nbsp;Concepts</a></h1>
<div class="section" id="concepts">
<h1><a class="toc-backref" href="#id30" 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">
<h2><a class="toc-backref" href="#id33" id="argumentpack" name="argumentpack">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></h2>
<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>
<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">
<h3><a id="requirements" name="requirements">Requirements</a></h3>
<div class="section" id="requirements">
<h3><a 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>
@@ -200,10 +194,10 @@ will be propagated to the caller.</p>
<col width="40%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Expression</th>
<th class="head">Type</th>
<th class="head">Requirements</th>
<th class="head">Semantics/Notes</th>
<tr><th>Expression</th>
<th>Type</th>
<th>Requirements</th>
<th>Semantics/Notes</th>
</tr>
</thead>
<tbody valign="top">
@@ -242,14 +236,14 @@ all the elements of both <tt class="docutils literal"><span class="pre">x</span>
</table>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id34" id="id5" name="id5"><span id="parameterspec"></span>3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></h2>
<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>
<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>
<ul class="simple" id="conditions">
<span class="target" id="conditions"></span><ul class="simple">
<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>
@@ -262,9 +256,9 @@ argument type. In each row,</p>
<col width="47%" />
</colgroup>
<thead valign="bottom">
<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><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>
</thead>
<tbody valign="top">
@@ -289,10 +283,10 @@ arguments that will be matched by <a class="reference" href="index.html#forwardi
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id35" id="class-templates" name="class-templates">4&nbsp;&nbsp;&nbsp;Class Templates</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id36" 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>
<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>
<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" />
@@ -317,7 +311,7 @@ struct keyword
static keyword&lt;Tag&gt;&amp; <a class="reference" href="#get">get</a>();
};
</pre>
<dl class="docutils" id="operator">
<span class="target" id="operator"></span><dl class="docutils">
<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;
@@ -336,7 +330,7 @@ template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="
</table>
</dd>
</dl>
<dl class="docutils" id="id9">
<span class="target" id="id9"></span><dl class="docutils">
<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;
@@ -352,7 +346,7 @@ template &lt;class T&gt; <em>tagged default</em> operator|(T const&amp; x) const
</table>
</dd>
</dl>
<dl class="docutils" id="id10">
<span class="target" id="id10"></span><dl class="docutils">
<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;
@@ -369,7 +363,7 @@ template &lt;class F&gt; <em>tagged lazy default</em> operator||(F const&amp; g)
</table>
</dd>
</dl>
<dl class="docutils" id="get">
<span class="target" id="get"></span><dl class="docutils">
<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();
@@ -389,8 +383,8 @@ simultaneously.</td>
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id37" id="parameters" name="parameters">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></h2>
<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>
<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
@@ -417,10 +411,8 @@ struct parameters
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&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="vellipsis"> .
.
.
</span>
<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>
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;
};
@@ -443,11 +435,11 @@ follows, for any argument type <tt class="docutils literal"><span class="pre">A<
<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"><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>
@@ -455,7 +447,7 @@ follows, for any argument type <tt class="docutils literal"><span class="pre">A<
</div>
</blockquote>
</div>
<dl class="docutils" id="match">
<span class="target" id="match"></span><dl class="docutils">
<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">
@@ -486,13 +478,11 @@ every <em>j</em> in 0…β, either:</p>
</ul>
</dd>
</dl>
<dl class="docutils" id="id13">
<span class="target" id="id13"></span><dl class="docutils">
<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="vellipsis"> .
.
.
</span>
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>
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">
@@ -511,8 +501,8 @@ template &lt;class A0, …class Aβ&gt; <a class="reference" href="#argumentpack
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id38" 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>
<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>
<p>These templates describe the requirements on a function parameter.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@@ -543,12 +533,12 @@ struct required;
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id39" id="metafunctions" name="metafunctions">5&nbsp;&nbsp;&nbsp;Metafunctions</a></h1>
<div class="section" id="metafunctions">
<h1><a class="toc-backref" href="#id37" 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">
<h2><a class="toc-backref" href="#id40" id="binding" name="binding">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></h2>
<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>
<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">
@@ -578,8 +568,8 @@ having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt cl
</tbody>
</table>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id41" id="lazy-binding" name="lazy-binding">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></h2>
<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>
<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" />
@@ -610,136 +600,12 @@ having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt cl
</div>
</div>
<hr class="docutils" />
<div class="section">
<h1><a class="toc-backref" href="#id42" id="code-generation-macros" name="code-generation-macros">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a></h1>
<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>
<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">
<h2><a class="toc-backref" href="#id43" 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 ::= specifier-group {specifier-group}
specifier-group ::= ( '(' 'optional' optional-specifier {optional-specifier} ')' ) |
( '(' 'required' required-specifier {required-specifier} ')' )
optional-specifier ::= '(' name ',' restriction ',' default-value ')'
required-specifier ::= '(' name ',' restriction ')'
restriction ::= ('*' '(' lambda-expression ')' ) |
( '(' typename ')' ) |
'*'
</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="#id44" id="boost-parameter-fun-r-n-l-h-p" name="boost-parameter-fun-r-n-l-h-p">6.2&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" 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>
<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
@@ -779,10 +645,8 @@ r name(
, typename <strong>p</strong>::match&lt;A1,A2,…A<strong>l</strong>,A##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)&gt;::type p = <strong>p</strong>())
{
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="vellipsis"> .
.
.
</span>
}
<span class="doublesize"></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>
@@ -794,8 +658,8 @@ r name(
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id45" id="boost-parameter-keyword-n-k" name="boost-parameter-keyword-n-k">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></h2>
<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>
<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>
@@ -811,7 +675,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();
}
@@ -819,8 +683,8 @@ namespace {
</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id46" id="boost-parameter-match-p-a-x" name="boost-parameter-match-p-a-x">6.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></h2>
<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>
<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">
@@ -835,7 +699,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>)
@@ -853,10 +717,10 @@ typename <strong>p</strong>::match&lt;<strong>A0</strong>,<strong>A1</strong>…
</dl>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id47" id="configuration-macros" name="configuration-macros">7&nbsp;&nbsp;&nbsp;Configuration Macros</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id48" 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>
<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>
<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>
@@ -878,8 +742,8 @@ already <tt class="docutils literal"><span class="pre">#defined</span></tt>.</p>
</table>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id49" id="tutorial" name="tutorial">8&nbsp;&nbsp;&nbsp;Tutorial</a></h1>
<div class="section" id="tutorial">
<h1><a class="toc-backref" href="#id46" 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" />
@@ -904,11 +768,10 @@ where it could make a difference.</td></tr>
</table>
</div>
</div>
<hr class="docutils footer" />
<div class="footer">
<hr class="footer" />
Generated on: 2006-07-26 15:39 UTC.
Generated on: 2006-01-27 01:56 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

@@ -13,12 +13,6 @@ img {
vertical-align: middle
}
span.vellipsis {
line-height: 30% ;
font-size: 200% ;
}
PRE
{
FONT-FAMILY: monospace ;

File diff suppressed because it is too large Load Diff

View File

@@ -1,771 +0,0 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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,6 +2,13 @@
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`_
@@ -12,13 +19,6 @@
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
@@ -42,8 +42,9 @@ __ ../../../../index.htm
.. |ForwardSequence| replace:: :concept:`Forward Sequence`
.. |ParameterSpec| replace:: :concept:`ParameterSpec`
.. role:: vellipsis
:class: vellipsis
.. role:: large
:class: doublesize
.. section-numbering::
:depth: 2
@@ -384,11 +385,8 @@ __ ../../../../boost/parameter/parameters.hpp
|ArgumentPack|_ `operator()`_\(A0 const& a0) const;
template <class A0, class A1>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1) const; :vellipsis:`\
.
.
.
`
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1) const;
:large:`⋮`
template <class A0, class A1, …class A\ β>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1, …A\ β const& a\ β) const;
};
@@ -443,11 +441,8 @@ __ ../../../../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;
:large:`⋮`
template <class A0, …class A\ β> |ArgumentPack|_ `operator()`_\(A0 const& a0, …A\ β const& a\ β) const;
:Returns:
@@ -554,113 +549,6 @@ 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-group ::= ( '(' '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_FUN(r,n,l,h,p)``
----------------------------------
@@ -694,11 +582,8 @@ 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:`\
.
.
.
`
}
:large:`⋮`
template <class A1, class A2, …class A\ **h**>
r name(
A1 const& a1, A2 const& a2, …A\ **h** const& x\ **h**
@@ -798,5 +683,4 @@ __ 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

@@ -0,0 +1,438 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 ARG_LIST_050329_HPP
#define ARG_LIST_050329_HPP
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/result_of0.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/maybe_fwd.hpp>
#include <boost/parameter/config.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/iterator_tags.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/optional.hpp>
namespace boost { namespace parameter {
// Forward declaration for aux::arg_list, below.
template<class T> struct keyword;
namespace aux {
//
// Structures used to build the tuple of actual arguments. The
// tuple is a nested cons-style list of arg_list specializations
// terminated by an empty_arg_list.
//
// Each specialization of arg_list is derived from its successor in
// the list type. This feature is used along with using
// declarations to build member function overload sets that can
// match against keywords.
//
// MPL sequence support
struct arg_list_tag;
// Terminates arg_list<> and represents an empty list. Since this
// is just the terminating case you might want to look at arg_list
// first, to get a feel for what's really happening here.
struct empty_arg_list
{
empty_arg_list() {}
// Constructor taking BOOST_PARAMETER_MAX_ARITY empty_arg_list
// arguments; this makes initialization
empty_arg_list(
BOOST_PP_ENUM_PARAMS(
BOOST_PARAMETER_MAX_ARITY, void_ BOOST_PP_INTERCEPT
))
{}
// A metafunction class that, given a keyword and a default
// type, returns the appropriate result type for a keyword
// lookup given that default
struct binding
{
template<class KW, class Default>
struct apply
{
typedef Default type;
};
};
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// Terminator for has_key, indicating that the keyword is unique
template <class KW>
static no_tag has_key(KW*);
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| (BOOST_WORKAROUND(__GNUC__, < 3)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// The overload set technique doesn't work with these older
// compilers, so they need some explicit handholding.
// A metafunction class that, given a keyword, returns the type
// of the base sublist whose get() function can produce the
// value for that key
struct key_owner
{
template<class KW>
struct apply
{
typedef empty_arg_list type;
};
};
template <class K, class T>
T& get(default_<K,T> x) const
{
return x.value;
}
template <class K, class F>
typename result_of0<F>::type
get(lazy_default<K,F> x) const
{
return x.compute_default();
}
#endif
// If this function is called, it means there is no argument
// in the list that matches the supplied keyword. Just return
// the default value.
template <class K, class Default>
Default& operator[](default_<K, Default> x) const
{
return x.value;
}
// If this function is called, it means there is no argument
// in the list that matches the supplied keyword. Just evaluate
// and return the default value.
template <class K, class F>
typename result_of0<F>::type
operator[](
BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
{
return x.compute_default();
}
// No argument corresponding to ParameterRequirements::key_type
// 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>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
// MPL sequence support
typedef empty_arg_list type; // convenience
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<class KW>
no_tag operator*(empty_arg_list, KW*);
#endif
// Forward declaration for arg_list::operator,
template <class KW, class T>
struct tagged_argument;
// A tuple of tagged arguments, terminated with empty_arg_list.
// Every TaggedArg is an instance of tagged_argument<>.
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::value_type value_type;
typedef typename TaggedArg::reference reference;
TaggedArg arg; // Stores the argument
// Store the arguments in successive nodes of this list
template< // class A0, class A1, ...
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
>
arg_list( // A0 const& a0, A1 const& a1, ...
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, const & a)
)
: Next( // a1, a2, ...
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
, void_()
)
, arg(a0)
{}
// Create a new list by prepending arg to a copy of tail. Used
// when incrementally building this structure with the comma
// operator.
arg_list(TaggedArg arg, Next const& tail)
: Next(tail)
, arg(arg)
{}
// A metafunction class that, given a keyword and a default
// type, returns the appropriate result type for a keyword
// lookup given that default
struct binding
{
template <class KW, class Default>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
>::type type;
};
};
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !BOOST_WORKAROUND(__GNUC__, == 2)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
friend yes_tag operator*(arg_list, key_type*);
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) (*(next*)0 * (key*)0)
# else
// Overload for key_type, so the assert below will fire if the
// same keyword is used again
static yes_tag has_key(key_type*);
using Next::has_key;
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
# endif
BOOST_MPL_ASSERT_MSG(
sizeof(BOOST_PARAMETER_CALL_HAS_KEY(Next,key_type)) == sizeof(no_tag)
, duplicate_keyword, (key_type)
);
# undef BOOST_PARAMETER_CALL_HAS_KEY
#endif
//
// Begin implementation of indexing operators for looking up
// specific arguments by name
//
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__GNUC__, < 3) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// These older compilers don't support the overload set creation
// idiom well, so we need to do all the return type calculation
// for the compiler and dispatch through an outer function template
// A metafunction class that, given a keyword, returns the base
// sublist whose get() function can produce the value for that
// key.
struct key_owner
{
template<class KW>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<arg_list<TaggedArg,Next> >
, mpl::apply_wrap1<typename Next::key_owner,KW>
>::type type;
};
};
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap2<binding, KW, void_>::type
operator[](keyword<KW> const& x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
return sublist.get(x);
}
template <class KW, class Default>
typename mpl::apply_wrap2<binding, KW, Default&>::type
operator[](default_<KW, Default> x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
return sublist.get(x);
}
template <class KW, class F>
typename mpl::apply_wrap2<
binding,KW
, typename result_of0<F>::type
>::type
operator[](lazy_default<KW,F> x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
return sublist.get(x);
}
// These just return the stored value; when empty_arg_list is
// reached, indicating no matching argument was passed, the
// default is returned, or if no default_ or lazy_default was
// passed, compilation fails.
reference get(keyword<key_type> const&) const
{
return arg.value;
}
template <class Default>
reference get(default_<key_type,Default>) const
{
return arg.value;
}
template <class Default>
reference get(lazy_default<key_type, Default>) const
{
return arg.value;
}
#else
typedef typename mpl::eval_if<
is_maybe<value_type>
, get_reference<value_type>
, mpl::identity<reference>
>::type default_reference;
reference operator[](keyword<key_type> const&) const
{
return arg.value;
}
template <class T, class D>
default_reference get_value(T&, D&) const
{
return arg.value;
}
template <class T, class D>
default_reference get_value(maybe<T>&, D& x) const
{
return arg.value ? arg.value.get() : x;
}
template <class Default>
default_reference operator[](default_<key_type, Default> const& x) const
{
return get_value(arg.value, x.value);
}
template <class Default>
reference operator[](lazy_default<key_type, Default>) const
{
return arg.value;
}
// Builds an overload set including operator[]s defined in base
// classes.
using Next::operator[];
//
// End of indexing support
//
//
// For parameter_requirements matching this node's key_type,
// return a bool constant wrapper indicating whether the
// requirements are satisfied by TaggedArg. Used only for
// 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
satisfies(
parameter_requirements<key_type,Predicate,HasDefault>*
);
// Builds an overload set including satisfies functions defined
// in base classes.
using Next::satisfies;
#endif
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class KW, class T2>
arg_list<tagged_argument<KW, T2>, self>
operator,(tagged_argument<KW,T2> x)
{
return arg_list<tagged_argument<KW,T2>, self>(x, *this);
}
// MPL sequence support
typedef self type; // Convenience for users
typedef Next tail_type; // For the benefit of iterators
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
template <> struct arg_list<int,int> {};
#endif
// MPL sequence support
template <class ArgumentPack>
struct arg_list_iterator
{
typedef mpl::forward_iterator_tag category;
// The incremented iterator
typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
// dereferencing yields the key type
typedef typename ArgumentPack::key_type type;
};
template <>
struct arg_list_iterator<empty_arg_list> {};
}} // namespace parameter::aux
// MPL sequence support
namespace mpl
{
template <>
struct begin_impl<parameter::aux::arg_list_tag>
{
template <class S>
struct apply
{
typedef parameter::aux::arg_list_iterator<S> type;
};
};
template <>
struct end_impl<parameter::aux::arg_list_tag>
{
template <class>
struct apply
{
typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
};
};
}
} // namespace boost
#endif // ARG_LIST_050329_HPP

View File

@@ -0,0 +1,67 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 DEFAULT_050329_HPP
#define DEFAULT_050329_HPP
namespace boost { namespace parameter { namespace aux {
// A wrapper for the default value passed by the user when resolving
// the value of the parameter with the given Keyword
template <class Keyword, class Value>
struct default_
{
default_(Value& x)
: value(x)
{}
Value& value;
};
//
// lazy_default --
//
// A wrapper for the default value computation function passed by
// the user when resolving the value of the parameter with the
// given keyword
//
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 300)
// These compilers need a little extra help with overload
// resolution; we have empty_arg_list's operator[] accept a base
// class to make that overload less preferable.
template <class KW, class DefaultComputer>
struct lazy_default_base
{
lazy_default_base(DefaultComputer const& x)
: compute_default(x)
{}
DefaultComputer const& compute_default;
};
template <class KW, class DefaultComputer>
struct lazy_default
: lazy_default_base<KW,DefaultComputer>
{
lazy_default(DefaultComputer const & x)
: lazy_default_base<KW,DefaultComputer>(x)
{}
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
#else
template <class KW, class DefaultComputer>
struct lazy_default
{
lazy_default(const DefaultComputer& x)
: compute_default(x)
{}
DefaultComputer const& compute_default;
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
#endif
}}} // namespace boost::parameter::aux
#endif // DEFAULT_050329_HPP

View File

@@ -0,0 +1,52 @@
// Copyright Daniel Wallin 2005. 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_MAYBE_051212_HPP
# define BOOST_PARAMETER_MAYBE_051212_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/mpl/if.hpp>
namespace boost { namespace parameter { namespace aux {
struct empty_maybe_tag {};
template <class T>
struct maybe
{
typedef typename mpl::if_<
is_reference<T>
, T
, typename add_reference<typename add_const<T>::type>::type
>::type reference;
maybe()
{}
explicit maybe(reference x)
: value(x)
{}
typedef reference(maybe<T>::*safe_bool)() const;
operator safe_bool() const
{
return value ? &maybe<T>::get : 0 ;
}
reference get() const
{
return value.get();
}
boost::optional<T> value;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_MAYBE_051212_HPP

View File

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin 2005. 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_MAYBE_FWD_051212_HPP
# define BOOST_PARAMETER_MAYBE_FWD_051212_HPP
# include <boost/detail/is_xxx.hpp>
namespace boost { namespace parameter { namespace aux {
template <class T>
struct maybe;
BOOST_DETAIL_IS_XXX_DEF(maybe,maybe,1)
template <class T>
struct get_reference
{
typedef typename T::reference type;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_MAYBE_FWD_051212_HPP

View File

@@ -0,0 +1,77 @@
// 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)
// This file generates overloads in this format:
//
// template<class A0, class A1>
// typename mpl::apply_wrap1<
// aux::make_arg_list<
// PS0,A0
// , aux::make_arg_list<
// PS1,A1
// , mpl::identity<aux::empty_arg_list>
// >
// >
// , unnamed_list
// >::type
// operator()(A0 const& a0, A1 const& a1) const
// {
// typedef typename mpl::apply_wrap1<
// aux::make_arg_list<
// PS0,A0
// , aux::make_arg_list<
// PS1,A1
// , mpl::identity<aux::empty_arg_list>
// >
// >
// >::type arg_tuple;
//
// return arg_tuple(
// a0
// , a1
// , aux::void_()
// ...
// );
// }
//
#if !defined(BOOST_PP_IS_ITERATING)
# error Boost.Parameters - do not include this file!
#endif
#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)
#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>
template<BOOST_PP_ENUM_PARAMS(N, class A)>
typename BOOST_PARAMETER_arg_list(N)::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const
{
typedef typename BOOST_PARAMETER_arg_list(N)::type arg_tuple;
return arg_tuple(
BOOST_PP_ENUM_PARAMS(N, a)
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N)
, aux::void_() BOOST_PP_INTERCEPT
));
}
#undef BOOST_PARAMETER_arg_list
#undef BOOST_PARAMETER_open_list
#undef BOOST_PARAMETER_close_list
#undef N

View File

@@ -0,0 +1,25 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 PARAMETER_REQUIREMENTS_050331_HPP
#define PARAMETER_REQUIREMENTS_050331_HPP
namespace boost { namespace parameter { namespace aux {
// Used to pass static information about parameter requirements
// through the satisfies() overload set (below). The
// matched function is never invoked, but its type indicates whether
// a parameter matches at compile-time
template <class Keyword, class Predicate, class HasDefault>
struct parameter_requirements
{
typedef Keyword keyword;
typedef Predicate predicate;
typedef HasDefault has_default;
};
}}} // namespace boost::parameter::aux
#endif // PARAMETER_REQUIREMENTS_050331_HPP

View File

@@ -0,0 +1,36 @@
// Copyright David Abrahams 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)
#ifndef BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP
# define BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP
# include <boost/utility/result_of.hpp>
// A metafunction returning the result of invoking a nullary function
// object of the given type.
#ifndef BOOST_NO_RESULT_OF
# include <boost/utility/result_of.hpp>
namespace boost { namespace parameter { namespace aux {
template <class F>
struct result_of0 : result_of<F()>
{};
}}} // namespace boost::parameter::aux_
#else
namespace boost { namespace parameter { namespace aux {
template <class F>
struct result_of0
{
typedef typename F::result_type type;
};
}}} // namespace boost::parameter::aux_
#endif
#endif // BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP

View File

@@ -0,0 +1,38 @@
// Copyright David Abrahams 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)
#ifndef BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
# define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
# include <boost/parameter/aux_/unwrap_cv_reference.hpp>
# include <boost/parameter/aux_/tagged_argument.hpp>
namespace boost { namespace parameter { namespace aux {
template <class Keyword, class ActualArg
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, class = typename is_cv_reference_wrapper<ActualArg>::type
#endif
>
struct tag
{
typedef tagged_argument<
Keyword
, typename unwrap_cv_reference<ActualArg>::type
> type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Keyword, class ActualArg>
struct tag<Keyword,ActualArg,mpl::false_>
{
typedef tagged_argument<
Keyword
, ActualArg
> type;
};
#endif
}}} // namespace boost::parameter::aux_
#endif // BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP

View File

@@ -0,0 +1,60 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 TAGGED_ARGUMENT_050328_HPP
#define TAGGED_ARGUMENT_050328_HPP
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/arg_list.hpp>
#include <boost/detail/is_xxx.hpp>
namespace boost { namespace parameter { namespace aux {
// Holds a reference to an argument of type Arg associated with
// keyword Keyword
template <class Keyword, class Arg>
struct tagged_argument
{
typedef Keyword key_type;
typedef Arg value_type;
typedef Arg& reference;
tagged_argument(reference x) : value(x) {}
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class Keyword2, class Arg2>
arg_list<
tagged_argument<Keyword, Arg>
, arg_list<tagged_argument<Keyword2, Arg2> >
>
operator,(tagged_argument<Keyword2, Arg2> x) const
{
return arg_list<
tagged_argument<Keyword, Arg>
, arg_list<tagged_argument<Keyword2, Arg2> >
>(
*this
, arg_list<tagged_argument<Keyword2, Arg2> >(x, empty_arg_list())
);
}
reference value;
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
// warning suppression
private:
void operator=(tagged_argument const&);
#endif
};
// Defines a metafunction, is_tagged_argument, that identifies
// tagged_argument specializations.
BOOST_DETAIL_IS_XXX_DEF(tagged_argument,tagged_argument,2)
}}} // namespace boost::parameter::aux
#endif // TAGGED_ARGUMENT_050328_HPP

View File

@@ -0,0 +1,97 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 UNWRAP_CV_REFERENCE_050328_HPP
#define UNWRAP_CV_REFERENCE_050328_HPP
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
namespace boost { template<class T> class reference_wrapper; }
namespace boost { namespace parameter { namespace aux {
//
// reference_wrapper support -- because of the forwarding problem,
// when passing arguments positionally by non-const reference, we
// ask users of named parameter interfaces to use ref(x) to wrap
// them.
//
// is_cv_reference_wrapper returns mpl::true_ if T is of type
// reference_wrapper<U> cv
template <class U>
yes_tag is_cv_reference_wrapper_check(reference_wrapper<U> const volatile*);
no_tag is_cv_reference_wrapper_check(...);
template <class T>
struct is_cv_reference_wrapper
{
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag)
)
);
typedef mpl::bool_<
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
is_cv_reference_wrapper::
#endif
value> type;
};
#if BOOST_WORKAROUND(MSVC, == 1200)
template <>
struct is_cv_reference_wrapper<int>
: mpl::false_ {};
#endif
// Needed for unwrap_cv_reference below. T might be const, so
// eval_if might fail because of deriving from T const on EDG.
template <class T>
struct get_type
{
typedef typename T::type type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
struct unwrap_cv_reference
{
typedef T type;
};
template <class T>
struct unwrap_cv_reference<T const, mpl::false_>
{
typedef T const type;
};
template <class T>
struct unwrap_cv_reference<T, mpl::true_>
: T
{};
#else
// Produces the unwrapped type to hold a reference to in named<>
// Can't use boost::unwrap_reference<> here because it
// doesn't handle the case where T = reference_wrapper<U> cv
template <class T>
struct unwrap_cv_reference
{
typedef typename mpl::eval_if<
is_cv_reference_wrapper<T>
, get_type<T>
, mpl::identity<T>
>::type type;
};
#endif
}}} // namespace boost::parameter::aux
#endif // UNWRAP_CV_REFERENCE_050328_HPP

View File

@@ -0,0 +1,18 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 VOID_050329_HPP
#define VOID_050329_HPP
namespace boost { namespace parameter { namespace aux {
// A placemarker for "no argument passed."
// MAINTAINER NOTE: Do not make this into a metafunction
struct void_ {};
}}} // namespace boost::parameter::aux
#endif // VOID_050329_HPP

View File

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 YESNO_050328_HPP
#define YESNO_050328_HPP
#include <boost/mpl/bool.hpp>
namespace boost { namespace parameter { namespace aux {
// types used with the "sizeof trick" to capture the results of
// overload resolution at compile-time.
typedef char yes_tag;
typedef char (&no_tag)[2];
// mpl::true_ and mpl::false_ are not distinguishable by sizeof(),
// so we pass them through these functions to get a type that is.
yes_tag to_yesno(mpl::true_);
no_tag to_yesno(mpl::false_);
}}} // namespace boost::parameter::aux
#endif // YESNO_050328_HPP

View File

@@ -0,0 +1,57 @@
// Copyright David Abrahams 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)
#ifndef BOOST_PARAMETER_BINDING_DWA200558_HPP
# define BOOST_PARAMETER_BINDING_DWA200558_HPP
# include <boost/mpl/apply.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.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)
template <class Parameters, class Keyword, class Default = void>
struct binding
: mpl::apply_wrap2<
typename Parameters::binding,Keyword,Default
>
{};
# else
template <class Parameters, class Keyword, class Default = aux::void_>
struct binding
{
typedef typename mpl::apply_wrap2<
typename Parameters::binding,Keyword,
typename mpl::if_<is_same<Default,aux::void_>,void,Default>::type
>::type type;
};
# 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_binding
{
typedef typename mpl::apply_wrap2<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
>::type type;
};
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_BINDING_DWA200558_HPP

View File

@@ -0,0 +1,14 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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_CONFIG_050403_HPP
#define BOOST_PARAMETER_CONFIG_050403_HPP
#ifndef BOOST_PARAMETER_MAX_ARITY
# define BOOST_PARAMETER_MAX_ARITY 5
#endif
#endif // BOOST_PARAMETER_CONFIG_050403_HPP

View File

@@ -0,0 +1,134 @@
// Copyright Daniel Wallin, David Abrahams 2005. 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 KEYWORD_050328_HPP
#define KEYWORD_050328_HPP
#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 {
// Instances of unique specializations of keyword<...> serve to
// associate arguments with parameter names. For example:
//
// struct rate_; // parameter names
// struct skew_;
// namespace
// {
// keyword<rate_> rate; // keywords
// keyword<skew_> skew;
// }
//
// ...
//
// f(rate = 1, skew = 2.4);
//
template <class Tag>
struct keyword : noncopyable
{
template <class T>
typename aux::tag<Tag, T>::type
operator=(T& x) const
{
typedef typename aux::tag<Tag, T>::type result;
return result(x);
}
template <class Default>
aux::default_<Tag, Default>
operator|(Default& default_) const
{
return aux::default_<Tag, Default>(default_);
}
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default& default_) const
{
return aux::lazy_default<Tag, Default>(default_);
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
template <class T>
typename aux::tag<Tag, T const>::type
operator=(T const& x) const
{
typedef typename aux::tag<Tag, T const>::type result;
return result(x);
}
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
template <class Default>
aux::default_<Tag, const Default>
operator|(const Default& default_) const
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
volatile
#endif
{
return aux::default_<Tag, const Default>(default_);
}
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default const& default_) const
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
volatile
#endif
{
return aux::lazy_default<Tag, Default>(default_);
}
#endif
public: // Insurance against ODR violations
// People will need to define these keywords in header files. To
// prevent ODR violations, it's important that the keyword used in
// every instantiation of a function template is the same object.
// We provide a reference to a common instance of each keyword
// object and prevent construction by users.
static keyword<Tag>& get()
{
static keyword<Tag> result;
return result;
}
private:
keyword() {}
};
// Reduces boilerplate required to declare and initialize keywords
// without violating ODR. Declares a keyword tag type with the given
// name in namespace tag_namespace, and declares and initializes a
// reference in an anonymous namespace to a singleton instance of that
// type.
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
static ::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get();
#else
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
namespace \
{ \
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get(); \
}
#endif
}} // namespace boost::parameter
#endif // KEYWORD_050328_HPP

View File

@@ -0,0 +1,98 @@
// 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)
#ifndef BOOST_PARAMETER_MACROS_050412_HPP
#define BOOST_PARAMETER_MACROS_050412_HPP
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/logical/bool.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/cat.hpp>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \
template<BOOST_PP_ENUM_PARAMS(n, class T)>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n)
#ifndef BOOST_NO_SFINAE
# define BOOST_PARAMETER_MATCH_TYPE(n, param) \
BOOST_PP_EXPR_IF(n, typename) param::match \
< \
BOOST_PP_ENUM_PARAMS(n, T) \
>::type
#else
# define BOOST_PARAMETER_MATCH_TYPE(n, param) param
#endif
#define BOOST_PARAMETER_FUN_DECL(z, n, params) \
\
BOOST_PP_CAT(BOOST_PARAMETER_FUN_TEMPLATE_HEAD, BOOST_PP_BOOL(n))(n) \
\
BOOST_PP_TUPLE_ELEM(3, 0, params) \
BOOST_PP_TUPLE_ELEM(3, 1, params)( \
BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& p) \
BOOST_PP_COMMA_IF(n) \
BOOST_PARAMETER_MATCH_TYPE(n,BOOST_PP_TUPLE_ELEM(3, 2, params)) \
kw = BOOST_PP_TUPLE_ELEM(3, 2, params)() \
) \
{ \
return BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, params), _with_named_params)( \
kw(BOOST_PP_ENUM_PARAMS(n, p)) \
); \
}
// Generates:
//
// template<class Params>
// ret name ## _with_named_params(Params const&);
//
// template<class T0>
// ret name(T0 const& p0, typename parameters::match<T0>::type kw = parameters())
// {
// return name ## _with_named_params(kw(p0));
// }
//
// template<class T0, ..., class TN>
// ret name(T0 const& p0, ..., TN const& PN
// , typename parameters::match<T0, ..., TN>::type kw = parameters())
// {
// return name ## _with_named_params(kw(p0, ..., pN));
// }
//
// template<class Params>
// ret name ## _with_named_params(Params const&)
//
// lo and hi determines the min and max arity of the generated functions.
#define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p); \
\
BOOST_PP_REPEAT_FROM_TO( \
lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p)
#define BOOST_PARAMETER_MEMFUN(ret, name, lo, hi, parameters) \
\
BOOST_PP_REPEAT_FROM_TO( \
lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p)
#endif // BOOST_PARAMETER_MACROS_050412_HPP

View File

@@ -0,0 +1,55 @@
// Copyright David Abrahams 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)
#ifndef BOOST_PARAMETER_MATCH_DWA2005714_HPP
# define BOOST_PARAMETER_MATCH_DWA2005714_HPP
# include <boost/detail/workaround.hpp>
# include <boost/preprocessor/seq/enum.hpp>
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
// Temporary version of BOOST_PP_SEQ_ENUM until Paul M. integrates the workaround.
# define BOOST_PARAMETER_SEQ_ENUM_I(size,seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, size) seq
# define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PARAMETER_SEQ_ENUM_I(BOOST_PP_SEQ_SIZE(seq), seq)
# else
# define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PP_SEQ_ENUM(seq)
# endif
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/parameter/config.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \
BOOST_PP_ENUM_TRAILING_PARAMS( \
BOOST_PP_SUB( \
BOOST_PARAMETER_MAX_ARITY \
, BOOST_PP_SEQ_SIZE(ArgTypes) \
) \
, ::boost::parameter::aux::void_ BOOST_PP_INTERCEPT \
)
# else
# define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes)
# endif
//
// Generates, e.g.
//
// typename dfs_params::match<A1,A2>::type name = dfs_params()
//
// with workarounds for Borland compatibility.
//
# define BOOST_PARAMETER_MATCH(ParameterSpec, ArgTypes, name) \
typename ParameterSpec ::match< \
BOOST_PARAMETER_SEQ_ENUM(ArgTypes) \
BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \
>::type name = ParameterSpec ()
#endif // BOOST_PARAMETER_MATCH_DWA2005714_HPP

View File

@@ -0,0 +1,610 @@
// 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)
#ifndef BOOST_PARAMETERS_031014_HPP
#define BOOST_PARAMETERS_031014_HPP
#include <boost/detail/is_xxx.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#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/enum_shifted.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/parameter/aux_/arg_list.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tagged_argument.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/config.hpp>
namespace boost {
template<class T> class reference_wrapper;
namespace parameter {
namespace aux { struct use_default {}; }
// These templates can be used to describe the treatment of particular
// named parameters for the purposes of overload elimination with
// SFINAE, by placing specializations in the parameters<...> list. In
// order for a treated function to participate in overload resolution:
//
// - all keyword tags wrapped in required<...> must have a matching
// actual argument
//
// - The actual argument type matched by every keyword tag
// associated with a predicate must satisfy that predicate
//
// If a keyword k is specified without an optional<...> or
// required<...>, wrapper, it is treated as though optional<k> were
// specified.
//
// If a keyword k is specified with unnamed<...>, that keyword
// will be automatically deduced from the argument list.
//
template <class Tag, class Predicate = aux::use_default>
struct required
{
typedef Tag key_type;
typedef Predicate predicate;
};
template <class Tag, class Predicate = aux::use_default>
struct optional
{
typedef Tag key_type;
typedef Predicate predicate;
};
template <class Tag, class Predicate>
struct unnamed
{
typedef Tag key_type;
typedef Predicate predicate;
};
namespace aux
{
// Defines metafunctions, is_required and is_optional, that
// identify required<...>, optional<...> and unnamed<...> 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)
//
// key_type, has_default, and predicate --
//
// These metafunctions accept a ParameterSpec and extract the
// keyword tag, whether or not a default is supplied for the
// parameter, and the predicate that the corresponding actual
// argument type is required match.
//
// a ParameterSpec is a specialization of either keyword<...>,
// required<...>, optional<...> or unnamed<...>
//
// helper for key_type<...>, below.
template <class T>
struct get_key_type
{ typedef typename T::key_type type; };
template <class T>
struct key_type
: mpl::eval_if<
mpl::or_<
is_optional<T>
, is_required<T>
, is_unnamed<T>
>
, get_key_type<T>
, mpl::identity<T>
>
{
};
template <class T>
struct has_default
: mpl::not_<is_required<T> >
{};
// helper for get_predicate<...>, below
template <class T>
struct get_predicate_or_default
{
typedef T type;
};
template <>
struct get_predicate_or_default<use_default>
{
typedef mpl::always<mpl::true_> type;
};
// helper for predicate<...>, below
template <class T>
struct get_predicate
{
typedef typename
get_predicate_or_default<typename T::predicate>::type
type;
};
template <class T>
struct predicate
: mpl::eval_if<
mpl::or_<
is_optional<T>
, is_required<T>
, is_unnamed<T>
>
, get_predicate<T>
, mpl::identity<mpl::always<mpl::true_> >
>
{
};
// 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
// by a satisfies(...) member function in arg_list.
template <class ParameterSpec>
struct as_parameter_requirements
{
typedef parameter_requirements<
typename key_type<ParameterSpec>::type
, typename predicate<ParameterSpec>::type
, typename has_default<ParameterSpec>::type
> type;
};
// 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 DefaultTag, class Arg, class UnnamedList>
struct as_tagged_argument
: mpl::eval_if<
is_tagged_argument<Arg>
, mpl::identity<mpl::pair<Arg, UnnamedList> >
, mpl::apply_wrap2<UnnamedList, Arg, DefaultTag>
>
{};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
template <>
struct as_tagged_argument<int,int,int>
{
typedef int type;
};
#endif
// Returns mpl::true_ iff the given ParameterRequirements are
// satisfied by ArgList.
template <class ArgList, class ParameterRequirements>
struct satisfies
{
#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<
typename ArgList::binding
, typename ParameterRequirements::keyword
, void_
>::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
>
>::type type;
#else
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(
aux::to_yesno(
ArgList::satisfies((ParameterRequirements*)0)
)
) == sizeof(yes_tag)
)
);
typedef mpl::bool_<satisfies::value> type;
#endif
};
// Returns mpl::true_ if the requirements of the given ParameterSpec
// are satisfied by ArgList.
template <class ArgList, class ParameterSpec>
struct satisfies_requirements_of
: satisfies<
ArgList
, typename as_parameter_requirements<ParameterSpec>::type
>
{};
// 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 TailFn>
struct make_arg_list
{
template <class UnnamedList>
struct apply
{
typedef typename as_tagged_argument<
typename key_type<ParameterSpec>::type,ArgumentType,UnnamedList
>::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;
};
};
// 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 TailFn
>
struct make_partial_arg_list
{
template <class UnnamedList>
struct apply
: mpl::eval_if<
is_same<ArgumentType, void_>
, mpl::identity<empty_arg_list>
, mpl::apply_wrap1<
make_arg_list<ParameterSpec, ArgumentType, TailFn>
, UnnamedList
>
>
{};
};
// Generates:
//
// make<
// parameter_spec#0, argument_type#0
// , make<
// parameter_spec#1, argument_type#1
// , ... mpl::identity<aux::empty_arg_list>
// ...>
// >
#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),
#define BOOST_PARAMETER_right_angle(z, n, text) >
#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)) \
mpl::always<aux::empty_arg_list> \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
// Terminates an unnamed_list (below).
struct empty_unnamed_list
{
template <class Arg, class DefaultTag>
struct apply
{
// No unnamed predicate matched Arg, so we tag Arg with
// the DefaultTag.
// TODO: If we come here we should assert that the current
// ParameterSpec isn't an unnamed<> spec.
typedef mpl::pair<
typename tag<DefaultTag, Arg const>::type
, empty_unnamed_list
> type;
};
};
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
template<class T>
struct is_string_literal : mpl::false_
{};
template<int N>
struct is_string_literal<char const[N]> : mpl::true_
{};
#endif
// 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 DefaultTag>
struct eval_tail
{
typedef typename mpl::apply_wrap2<
Tail, Arg, DefaultTag
>::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 DefaultTag>
struct apply
{
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
typedef typename mpl::if_<
is_string_literal<Arg>
, char const*
, Arg
>::type const arg_type;
#else
typedef Arg const arg_type;
#endif
typedef typename mpl::eval_if<
typename mpl::apply1<typename ParameterSpec::predicate, Arg>::type
, mpl::pair<
typename tag<typename ParameterSpec::key_type, arg_type>::type
, Tail
>
,
#if BOOST_WORKAROUND(__GNUC__, < 3)
typename unnamed_list<ParameterSpec, Tail>::template
#endif
eval_tail<Arg, DefaultTag>
>::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) \
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) \
BOOST_PP_REPEAT( \
n, BOOST_PARAMETER_make_unnamed_list, (make)(parameter_spec)) \
mpl::identity<aux::empty_unnamed_list> \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
} // namespace aux
#define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = aux::void_
template<
class PS0
, BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _)
>
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;
// if the elements of NamedList match the criteria of overload
// resolution, returns a type which can be constructed from
// parameters. Otherwise, this is not a valid metafunction (no nested
// ::type).
#ifndef BOOST_NO_SFINAE
// If NamedList satisfies the PS0, PS1, ..., this is a
// metafunction returning parameters. Otherwise it
// has no nested ::type.
template <class NamedList>
struct match_base
: mpl::if_<
// mpl::and_<
// aux::satisfies_requirements_of<NamedList,PS0>
// , mpl::and_<
// aux::satisfies_requirements_of<NamedList,PS1>...
// ..., mpl::true_
// ...> >
# 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, _)
# undef BOOST_PARAMETER_satisfies
, mpl::identity<parameters>
, aux::void_
>
{};
#endif
// Specializations are to be used as an optional argument to
// eliminate overloads via SFINAE
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, = aux::void_ BOOST_PP_INTERCEPT
)
#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
), unnamed_list>::type
>::type
{};
# else
{
typedef parameters<
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)
> type;
};
# endif
//
// 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.
//
aux::empty_arg_list operator()() const
{
return aux::empty_arg_list();
}
template<class A0>
typename mpl::apply_wrap1<
aux::make_arg_list<PS0,A0, mpl::always<aux::empty_arg_list> >
, unnamed_list
>::type
operator()( A0 const& a0) const
{
typedef typename mpl::apply_wrap1<
aux::make_arg_list<PS0,A0, mpl::always<aux::empty_arg_list> >
, unnamed_list
>::type result_type;
return result_type(
a0
// , void_(), void_(), void_() ...
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
, aux::void_() BOOST_PP_INTERCEPT)
);
}
template<class A0, class A1>
typename mpl::apply_wrap1<
aux::make_arg_list<
PS0,A0
, aux::make_arg_list<
PS1,A1
, mpl::always<aux::empty_arg_list>
>
>
, unnamed_list
>::type
operator()(A0 const& a0, A1 const& a1) const
{
typedef typename mpl::apply_wrap1<
aux::make_arg_list<
PS0,A0
, aux::make_arg_list<
PS1,A1
, mpl::always<aux::empty_arg_list>
>
>
, unnamed_list
>::type result_type;
return result_type(
a0, a1
// , void_(), void_() ...
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
, aux::void_() BOOST_PP_INTERCEPT)
);
}
// Higher arities are handled by the preprocessor
#define BOOST_PP_ITERATION_PARAMS_1 (3,( \
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
};
} // namespace parameter
} // namespace boost
#endif // BOOST_PARAMETERS_031014_HPP

View File

@@ -0,0 +1,103 @@
// Copyright Daniel Wallin 2005. 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_INVOKER_051210_HPP
# define BOOST_PARAMETER_INVOKER_051210_HPP
# include <boost/mpl/begin.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/parameter/keyword.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
namespace boost { namespace parameter { namespace python { namespace aux {
template <long Arity, class M, class R, class Args>
struct invoker;
template <class M, class R>
struct make_invoker
{
template <class Args>
struct apply
{
typedef invoker<
mpl::size<Args>::value, M, R, Args
> type;
};
};
template <long Arity, class T, class R, class Args>
struct call_invoker;
template <class T, class R>
struct make_call_invoker
{
template <class Args>
struct apply
{
typedef call_invoker<
mpl::size<Args>::value, T, R, Args
> type;
};
};
template <long Arity, class T, class Args>
struct init_invoker;
template <class T>
struct make_init_invoker
{
template <class Args>
struct apply
{
typedef init_invoker<
mpl::size<Args>::value, T, Args
> type;
};
};
template <class M, class R, class Args>
struct invoker<0, M, R, Args>
{
static R execute()
{
return M()(boost::type<R>());
}
};
template <class T, class R, class Args>
struct call_invoker<0, T, R, Args>
{
static R execute(T& self)
{
return self();
}
};
template <class T, class Args>
struct init_invoker<0, T, Args>
{
static T* execute(T& self)
{
return new T;
}
};
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 1))
# include BOOST_PP_ITERATE()
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 2))
# include BOOST_PP_ITERATE()
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 3))
# include BOOST_PP_ITERATE()
}}}} // namespace boost::parameter::python::aux
#endif // BOOST_PARAMETER_INVOKER_051210_HPP

View File

@@ -0,0 +1,87 @@
// Copyright Daniel Wallin 2005. 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/preprocessor/cat.hpp>
#include <boost/preprocessor/dec.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define N BOOST_PP_ITERATION()
#define BOOST_PARAMETER_PY_ARG_TYPES(z, n, _) \
typedef typename mpl::next< \
BOOST_PP_CAT(iter,BOOST_PP_DEC(n)) \
>::type BOOST_PP_CAT(iter,n); \
\
typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type BOOST_PP_CAT(spec,n); \
typedef typename mpl::if_< \
mpl::and_< \
mpl::not_<typename BOOST_PP_CAT(spec,n)::required> \
, typename BOOST_PP_CAT(spec,n)::optimized_default \
> \
, parameter::aux::maybe<typename BOOST_PP_CAT(spec,n)::type> \
, typename BOOST_PP_CAT(spec,n)::type \
>::type BOOST_PP_CAT(arg,n); \
typedef typename BOOST_PP_CAT(spec,n)::keyword BOOST_PP_CAT(kw,n);
#if BOOST_PP_ITERATION_FLAGS() == 1
template <class M, class R, class Args>
struct invoker<N, M, R, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 2
template <class T, class R, class Args>
struct call_invoker<N, T, R, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 3
template <class T, class Args>
struct init_invoker<N, T, Args>
#endif
{
typedef typename mpl::begin<Args>::type iter0;
typedef typename mpl::deref<iter0>::type spec0;
typedef typename mpl::if_<
mpl::and_<
mpl::not_<typename spec0::required>
, typename spec0::optimized_default
>
, parameter::aux::maybe<typename spec0::type>
, typename spec0::type
>::type arg0;
typedef typename spec0::keyword kw0;
BOOST_PP_REPEAT_FROM_TO(1, N, BOOST_PARAMETER_PY_ARG_TYPES, ~)
static
#if BOOST_PP_ITERATION_FLAGS() == 1 || BOOST_PP_ITERATION_FLAGS() == 2
R
#else
T*
#endif
execute(
#if BOOST_PP_ITERATION_FLAGS() == 2
T& self
,
#endif
BOOST_PP_ENUM_BINARY_PARAMS(N, arg, a)
)
{
return
#if BOOST_PP_ITERATION_FLAGS() == 1
M()(
boost::type<R>()
, BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 2
self(
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 3
new T(
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#endif
}
};
#undef BOOST_PARAMETER_PY_ARG_TYPES
#undef N

View File

@@ -0,0 +1,494 @@
// Copyright Daniel Wallin 2005. 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_FUNCTION_051130_HPP
# define BOOST_PARAMETER_FUNCTION_051130_HPP
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/for.hpp>
# include <boost/preprocessor/detail/split.hpp>
# include <boost/preprocessor/facilities/is_empty.hpp>
# include <boost/preprocessor/tuple/eat.hpp>
# include <boost/preprocessor/logical/not.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/punctuation/comma_if.hpp>
# include <boost/preprocessor/seq/for_each.hpp>
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/seq/fold_left.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/arithmetic/add.hpp>
# include <boost/preprocessor/control/if.hpp>
# include <boost/preprocessor/repetition/repeat_from_to.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/implicit_cast.hpp>
# include <boost/parameter.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/bool.hpp>
# define ZKB_KEYWORD(tag_namespace,name) \
BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace \
{ \
struct name \
{ \
static inline char const* keyword() \
{ \
return #name; \
} \
}; \
}
//
// A ``spec`` is a 4-tuple defined as:
//
// ( qualifier , name , type, default )
//
// Where qualifier is one of ``required`` or ``optional``.
//
// Below are access macros to the different components of a spec
//
# define ZKB_spec_qualifier(spec) BOOST_PP_TUPLE_ELEM(4,0,spec)
# define ZKB_spec_name(spec) BOOST_PP_TUPLE_ELEM(4,1,spec)
# define ZKB_spec_type(spec) BOOST_PP_TUPLE_ELEM(4,2,spec)
# define ZKB_spec_default(spec) BOOST_PP_TUPLE_ELEM(4,3,spec)
//
// Split a sublist into qualifier and arg-list.
// The form for the sublist w is:
//
// [optional|required] (x,y ..)
//
// ZKB_sublist_qualifier(w) will return 'optional' or 'required'
// ZKB_sublist_args(w) will return (x,y ..)
//
# define ZKB_sublist_required(args)
# define ZKB_sublist_optional(args)
# define ZKB_sublist_split_required required,
# define ZKB_sublist_split_optional optional,
# define ZKB_sublist_split(sub) \
BOOST_PP_CAT(ZKB_sublist_split_, sub)
# define ZKB_sublist_qualifier(sub) \
BOOST_PP_SPLIT(0, ZKB_sublist_split(sub))
# define ZKB_sublist_args(sub) \
BOOST_PP_SPLIT(1, ZKB_sublist_split(sub))
# define ZKB_sublist(sub) \
[ ZKB_sublist_qualifier(sub) : ZKB_sublist_args(sub) ]
//
// Iteration through n-ary tuples seqs
//
# define ZKB_for_each_head_aux2(x,y) (x,y), ~
# define ZKB_for_each_head_aux3(x,y,z) (x,y,z), ~
# define ZKB_for_each_head_aux4(x,y,z,u) (x,y,z,u), ~
# define ZKB_for_each_head(n,x) \
BOOST_PP_SPLIT(0, BOOST_PP_CAT(ZKB_for_each_head_aux,n) x)
# define ZKB_for_each_pred_aux_ZKB_END_SENTINEL
# define ZKB_for_each_pred_aux_check(x) \
BOOST_PP_NOT(BOOST_PP_IS_EMPTY(BOOST_PP_CAT(ZKB_for_each_pred_aux_, x))), ~
# define ZKB_for_each_pred_aux2(x,y) ZKB_for_each_pred_aux_check(x)
# define ZKB_for_each_pred_aux3(x,y,z) ZKB_for_each_pred_aux_check(x)
# define ZKB_for_each_pred_aux4(x,y,z,u) ZKB_for_each_pred_aux_check(x)
# define ZKB_for_each_pred_aux0(n,x) BOOST_PP_CAT(ZKB_for_each_pred_aux,n) x
# define ZKB_for_each_pred(r, state) \
BOOST_PP_SPLIT( \
0 \
, ZKB_for_each_pred_aux0( \
BOOST_PP_TUPLE_ELEM(5,3,state) \
, BOOST_PP_TUPLE_ELEM(5,0,state) \
) \
)
# define ZKB_for_each_op(r, state) \
( \
BOOST_PP_TUPLE_EAT(BOOST_PP_TUPLE_ELEM(5,3,state)) \
BOOST_PP_TUPLE_ELEM(5,0,state) \
, BOOST_PP_TUPLE_ELEM(5,1,state) \
, BOOST_PP_TUPLE_ELEM(5,2,state) \
, BOOST_PP_TUPLE_ELEM(5,3,state) \
, BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(5,4,state)) \
)
# define ZKB_for_each_macro(r, state) \
BOOST_PP_TUPLE_ELEM(5,2,state)( \
r \
, BOOST_PP_TUPLE_ELEM(5,4,state) \
, ZKB_for_each_head( \
BOOST_PP_TUPLE_ELEM(5,3,state) \
, BOOST_PP_TUPLE_ELEM(5,0,state) \
) \
, BOOST_PP_TUPLE_ELEM(5,1,state) \
)
# define ZKB_for_each_build_end_sentinel(z,n,text) BOOST_PP_COMMA_IF(n) ZKB_END_SENTINEL
# define ZKB_for_each_build_end_sentinel_tuple(arity) \
( \
BOOST_PP_REPEAT(arity, ZKB_for_each_build_end_sentinel, _) \
)
# define ZKB_for_each_seq(arity, list, data, macro) \
BOOST_PP_FOR( \
(list ZKB_for_each_build_end_sentinel_tuple(arity), data, macro, arity, 0) \
, ZKB_for_each_pred \
, ZKB_for_each_op \
, ZKB_for_each_macro \
)
//
// ZKB_build_parameters
//
// Build a parameters<> specialization. tag_namespace is the namespace
// where the keywords reside. args is a sequence of spec's.
//
# define ZKB_build_parameters_aux(r,tag_namespace,i,elem) \
BOOST_PP_COMMA_IF(i) \
boost::parameter::ZKB_spec_qualifier(elem)< \
tag_namespace::ZKB_spec_name(elem) \
, boost::is_convertible<boost::mpl::_, ZKB_spec_type(elem)> \
>
# define ZKB_build_parameters(tag_namespace, args) \
boost::parameter::parameters< \
BOOST_PP_SEQ_FOR_EACH_I(ZKB_build_parameters_aux, tag_namespace, args) \
>
# define ZKB_formal_args(r, data, i, elem) \
BOOST_PP_COMMA_IF(i) ZKB_spec_type(elem) ZKB_spec_name(elem)
# define ZKB_build_function_declaration(result,name,args) \
result name( \
BOOST_PP_SEQ_FOR_EACH_I(ZKB_formal_args, _, args) \
)
# define ZKB_build_fwd_declaration(result,name,args) \
ZKB_build_function_declaration(result,name,args);
# define ZKB_actual_args_maybe_default_optional(spec) | ZKB_spec_default(spec)
# define ZKB_actual_args_maybe_default_required(spec)
# define ZKB_actual_args_maybe_default(spec) \
BOOST_PP_CAT( \
ZKB_actual_args_maybe_default_ \
, ZKB_spec_qualifier(spec) \
)(spec)
# define ZKB_actual_args(r, data, i, elem) \
BOOST_PP_COMMA_IF(i) \
boost::implicit_cast<ZKB_spec_type(elem)>( \
args[ZKB_spec_name(elem) ZKB_actual_args_maybe_default(elem)] \
)
# define ZKB_build_dispatch(result,name,args_) \
template <class Args> \
result BOOST_PP_CAT(name,_dispatch)(Args const& args) \
{ \
return name( \
BOOST_PP_SEQ_FOR_EACH_I(ZKB_actual_args, _, args_) \
); \
}
# define ZKB_calculate_arity_range_op_required 1
# define ZKB_calculate_arity_range_op_optional 0
# define ZKB_calculate_arity_range_op(s, state, spec) \
BOOST_PP_IF( \
BOOST_PP_CAT(ZKB_calculate_arity_range_op_, ZKB_spec_qualifier(spec)) \
, BOOST_PP_INC(state) \
, state \
)
# define ZKB_calculate_arity_range(args) \
( \
BOOST_PP_SEQ_FOLD_LEFT(ZKB_calculate_arity_range_op, 0, args) \
, BOOST_PP_SEQ_SIZE(args) \
)
# define ZKB_build_forwarding_functions_arity_nullary(n,data) \
inline BOOST_PP_TUPLE_ELEM(2,0,data) BOOST_PP_TUPLE_ELEM(2,1,data)() \
{ \
return BOOST_PP_CAT( \
BOOST_PP_TUPLE_ELEM(2,1,data) \
, _dispatch \
)( \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,1,data), _parameters)() \
); \
}
# define ZKB_build_forwarding_functions_arity_nary(n,data) \
template<BOOST_PP_ENUM_PARAMS(n, class A)> \
BOOST_PP_TUPLE_ELEM(2,0,data) BOOST_PP_TUPLE_ELEM(2,1,data)( \
BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& a) \
) \
{ \
return BOOST_PP_CAT( \
BOOST_PP_TUPLE_ELEM(2,1,data) \
, _dispatch \
)( \
BOOST_PP_CAT( \
BOOST_PP_TUPLE_ELEM(2,1,data) \
, _parameters \
)()(BOOST_PP_ENUM_PARAMS(n, a)) \
); \
}
# define ZKB_build_forwarding_functions_arity(z,n,data) \
BOOST_PP_IF( \
n \
, ZKB_build_forwarding_functions_arity_nary \
, ZKB_build_forwarding_functions_arity_nullary \
)(n,data)
# define ZKB_build_forwarding_functions0(result,name,arity_tuple) \
BOOST_PP_REPEAT_FROM_TO( \
BOOST_PP_TUPLE_ELEM(2,0,arity_tuple) \
, BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2,1,arity_tuple)) \
, ZKB_build_forwarding_functions_arity \
, (result,name) \
)
# define ZKB_build_forwarding_functions(result,name,args) \
ZKB_build_forwarding_functions0(result,name,ZKB_calculate_arity_range(args))
# define ZKB_build_meta_arg(r,data,i,spec) \
BOOST_PP_COMMA_IF(i) ZKB_spec_type(spec) BOOST_PP_CAT(a,i)
# define ZKB_build_meta_is_required_optional 0
# define ZKB_build_meta_is_required_required 1
# define ZKB_build_meta_is_required(spec) \
BOOST_PP_CAT(ZKB_build_meta_is_required_, ZKB_spec_qualifier(spec))
# define ZKB_build_meta_keywords(r,tag_namespace,i,spec) \
BOOST_PP_COMMA_IF(i) boost::mpl::pair< \
boost::mpl::bool_<ZKB_build_meta_is_required(spec)> \
, tag_namespace::ZKB_spec_name(spec) \
>
# define ZKB_build_meta_types(r,data,spec) , ZKB_spec_type(spec)
# define ZKB_build_meta_default(tag_namespace,spec) \
static ZKB_spec_type(spec) default_(tag_namespace::ZKB_spec_name(spec)) \
{ \
return ZKB_spec_default(spec); \
}
# define ZKB_build_meta_defaults(r,tag_namespace,spec) \
BOOST_PP_IF( \
ZKB_build_meta_is_required(spec) \
, BOOST_PP_TUPLE_EAT(2) \
, ZKB_build_meta_default \
)(tag_namespace,spec)
# define ZKB_build_meta(result,name,meta_name,tag_namespace,args) \
struct meta_name \
{ \
result operator()(BOOST_PP_SEQ_FOR_EACH_I(ZKB_build_meta_arg, ~, args)) const \
{ \
return name(BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(args), a)); \
} \
\
typedef BOOST_PP_CAT(boost::mpl::vector, BOOST_PP_SEQ_SIZE(args))< \
BOOST_PP_SEQ_FOR_EACH_I(ZKB_build_meta_keywords, tag_namespace, args) \
> keywords; \
\
typedef BOOST_PP_CAT(boost::mpl::vector, BOOST_PP_INC(BOOST_PP_SEQ_SIZE(args)))< \
result BOOST_PP_SEQ_FOR_EACH(ZKB_build_meta_types, ~, args) \
> signature; \
\
BOOST_PP_SEQ_FOR_EACH(ZKB_build_meta_defaults, tag_namespace, args) \
};
# define ZKB_FUNCTION_IMPL_AUX(result,name,meta_name,args,tag_namespace,with_fwd_declaration) \
BOOST_PP_IF( \
with_fwd_declaration \
, ZKB_build_fwd_declaration \
, BOOST_PP_TUPLE_EAT(3) \
)(result,name,args) \
typedef ZKB_build_parameters(tag_namespace,args) BOOST_PP_CAT(name,_parameters); \
ZKB_build_dispatch(result,name,args) \
ZKB_build_forwarding_functions(result,name,args) \
ZKB_build_meta(result,name,meta_name,tag_namespace,args) \
ZKB_build_function_declaration(result,name,args)
# define ZKB_FUNCTION_IMPL(result,name,meta_name,args,tag_namespace,with_fwd_declaration) \
ZKB_FUNCTION_IMPL_AUX( \
result \
, name \
, meta_name \
, ZKB_flatten_arg_spec(args) \
, tag_namespace \
, with_fwd_declaration \
)
# define ZKB_FUNCTION(result,name,meta_name,tag_namespace,args) \
ZKB_FUNCTION_IMPL(result,name,meta_name,args,tag_namespace,1)
# define ZKB_MEMBER(class_,result,name,meta_name,tag_namespace,args) \
ZKB_FUNCTION_IMPL(result,name,meta_name,args,tag_namespace,0)
//
// ZKB_flatten_arg_spec
//
// Flattens an argument list into normalized 4 arity tuple sequence form:
//
// (qualifier, name, type, default)
//
// Example:
//
// (required (x, int) (y, float))
// (optional (z, int, 0))
//
// Is converted to:
//
// ((required, x, int, ~)) ((required, y, float, ~)) ((optional, z, int, 0))
//
// This makes processing much simpler.
//
# define ZKB_qualifier_arity_required 2
# define ZKB_qualifier_arity_optional 3
# define ZKB_qualifier_arity(q) BOOST_PP_CAT(ZKB_qualifier_arity_,q)
# define ZKB_flatten_arg_spec_aux_required(r,n,elem,_) \
(( \
required \
, BOOST_PP_TUPLE_REM(2) elem \
, ~ \
))
# define ZKB_flatten_arg_spec_aux_optional(r,n,elem,_) \
(( \
optional \
, BOOST_PP_TUPLE_REM(3) elem \
))
# define ZKB_flatten_arg_spec_aux0(z,data,elem) \
ZKB_for_each_seq( \
ZKB_qualifier_arity(ZKB_sublist_qualifier(elem)) \
, ZKB_sublist_args(elem) \
, ~ \
, BOOST_PP_CAT(ZKB_flatten_arg_spec_aux_, ZKB_sublist_qualifier(elem)) \
)
# define ZKB_flatten_arg_spec(args) \
BOOST_PP_SEQ_FOR_EACH(ZKB_flatten_arg_spec_aux0, _, args)
// ?_FUNCTION() generates
//
// void f(int value, char const* name, float scale);
//
// template<class Args>
// void f_dispatch(Args const& args)
// {
// f(args[value], args[name], args[scale | 20.f]);
// }
//
// template<class A0>
// void f(A0 const& a0)
// {
// f_dispatch(f_parameters()(a0));
// }
//
// template<class A0, class A1>
// void f(A0 const& a0, A1 const& a1)
// {
// f_dispatch(f_parameters()(a0,a1));
// }
//
// template<class A0, class A1, class A2>
// void f(A0 const& a0, A1 const& a1, A2 const& a2)
// {
// f_dispatch(f_parameters()(a0,a1,a2));
// }
//
// void f(int value, char const* name, float scale)
//
// ---------------------------------------------------------------------------
//
// _MEMBER() generates
//
// template<class Args>
// void f_dispatch(Args const& args)
// {
// f(args[value], args[name], args[scale | 20.f]);
// }
//
// template<class A0>
// void f(A0 const& a0)
// {
// f_dispatch(f_parameters()(a0));
// }
//
// template<class A0, class A1>
// void f(A0 const& a0, A1 const& a1)
// {
// f_dispatch(f_parameters()(a0,a1));
// }
//
// template<class A0, class A1, class A2>
// void f(A0 const& a0, A1 const& a1, A2 const& a2)
// {
// f_dispatch(f_parameters()(a0,a1,a2));
// }
//
// void f(int value, char const* name, float scale)
//
// ---------------------------------------------------------------------------
//
// _CONSTRUCTOR() generates
//
// template<class A0>
// type(A0 const& a0)
// {
// this->init_dispatch(f_parameters()(a0));
// }
//
// template<class A0, class A1>
// type(A0 const& a0, A1 const& a1)
// {
// this->init_dispatch(f_parameters()(a0,a1));
// }
//
// template<class Args>
// void init_dispatch(Args const& args)
// {
// this->init(args[value], args[name], args[scale | 20.f]);
// }
//
// private:
// void init(int value, char const* name, float scale)
//
// *** OR ***
//
// template<class A0>
// type(A0 const& a0)
// : base(
// f_parameters()(a0)[value]
// , f_parameters()(a0)[name]
// , f_parameters()(a0)[scale | 20.f]
// )
// {}
//
// template<class A0, class A1>
// type(A0 const& a0, A1 const& a1)
// : base(
// f_parameters()(a0,a1)[value]
// , f_parameters()(a0,a1)[name]
// , f_parameters()(a0,a1)[scale | 20.f]
// )
// {}
#endif // BOOST_PARAMETER_FUNCTION_051130_HPP

View File

@@ -0,0 +1,606 @@
// Copyright Daniel Wallin 2005. 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_GENERAL_051210_HPP
# define BOOST_PARAMETER_GENERAL_051210_HPP
# include <boost/mpl/vector.hpp>
# include <boost/mpl/fold.hpp>
# include <boost/mpl/prior.hpp>
# include <boost/mpl/shift_right.hpp>
# include <boost/mpl/shift_left.hpp>
# include <boost/mpl/bitand.hpp>
# include <boost/mpl/pair.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/push_back.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/count_if.hpp>
# include <boost/mpl/transform.hpp>
# include <boost/mpl/front.hpp>
# include <boost/mpl/iterator_range.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/not.hpp>
# include <boost/type.hpp>
# include <boost/python/def.hpp>
# include <boost/parameter/python/aux_/invoker.hpp>
# include <boost/parameter/aux_/maybe.hpp>
namespace boost { namespace parameter { namespace python {
PyObject* init_sentinel()
{
static PyTypeObject sentinel_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"Boost.Parameter.Unspecified", /* tp_name */
PyType_Type.tp_basicsize, /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
};
assert(PyType_Ready(&sentinel_type) == 0);
return boost::python::upcast<PyObject>(&sentinel_type);
}
inline boost::python::handle<>& sentinel_value()
{
static boost::python::handle<> x;
return x;
}
struct empty_tag_to_python
{
empty_tag_to_python()
{
boost::python::to_python_converter<
boost::parameter::aux::empty_maybe_tag, empty_tag_to_python
>();
sentinel_value() = boost::python::handle<>(init_sentinel());
}
static PyObject* convert(boost::parameter::aux::empty_maybe_tag)
{
return boost::python::xincref(sentinel_value().get());
}
};
}}} // namespace boost::parameter::python
namespace boost { namespace python
{
// Converts a Python value to a maybe<T>
template <class T>
struct arg_from_python<parameter::aux::maybe<T> >
: arg_from_python<T>
{
arg_from_python(PyObject* p)
: arg_from_python<T>(p)
, empty(false)
{
if (parameter::python::sentinel_value().get() == p)
{
empty = true;
}
}
bool convertible() const
{
if (empty) return true;
return arg_from_python<T>::convertible();
}
boost::parameter::aux::maybe<T> operator()()
{
if (empty)
{
return boost::parameter::aux::maybe<T>();
}
else
{
return boost::parameter::aux::maybe<T>(
arg_from_python<T>::operator()()
);
}
}
bool empty;
};
}} // namespace boost::python
namespace boost { namespace parameter { namespace python {
namespace aux
{
template <class K>
struct is_optional
: mpl::not_<
mpl::or_<typename K::required, typename K::optimized_default>
>
{};
template <class K, class Required, class Optimized, class T>
struct arg_spec
{
typedef K keyword;
typedef Required required;
typedef T type;
typedef Optimized optimized_default;
};
template <class K, class T, class Optimized = mpl::false_>
struct make_arg_spec_impl
{
typedef arg_spec<
typename K::first, typename K::second, Optimized, T
> type;
};
template <class K, class T>
struct make_arg_spec_impl<K, T, typename K::third>
{
typedef arg_spec<
typename K::first, typename K::second, typename K::third, T
> type;
};
template <class K, class T>
struct make_arg_spec
: make_arg_spec_impl<K, T>
{
};
template <class Spec, class State>
struct combinations_op
{
typedef typename State::second bits;
typedef typename State::first result0;
typedef typename mpl::if_<
mpl::or_<
typename Spec::required
, typename Spec::optimized_default
, mpl::bitand_<bits, mpl::long_<1> >
>
, typename mpl::push_back<result0, Spec>::type
, result0
>::type result;
typedef typename mpl::if_<
mpl::or_<
typename Spec::required
, typename Spec::optimized_default
>
, bits
, typename mpl::shift_right<bits, mpl::long_<1> >::type
>::type next_bits;
typedef mpl::pair<
result
, next_bits
> type;
};
// Used as start value in the recursive arg() composition below.
struct no_keywords
{
template <class T>
T const& operator,(T const& x) const
{
return x;
}
};
template <class K>
char const* keyword_name(K*)
{
return K::keyword();
}
template <class Def, class F, class Iter, class End, class Keywords>
void def_combination_aux0(
Def def, F f, Iter, End, Keywords const& keywords, mpl::false_)
{
typedef typename mpl::deref<Iter>::type spec;
typedef typename spec::keyword kw;
def_combination_aux(
def, f, typename mpl::next<Iter>::type(), End()
, (
keywords, boost::python::arg(keyword_name((kw*)0))
)
);
}
template <class Def, class F, class Iter, class End, class Keywords>
void def_combination_aux0(
Def def, F f, Iter, End, Keywords const& keywords, mpl::true_)
{
typedef typename mpl::deref<Iter>::type spec;
typedef typename spec::keyword kw;
def_combination_aux(
def, f, typename mpl::next<Iter>::type(), End()
, (
keywords, boost::python::arg(kw::keyword())
= boost::parameter::aux::empty_maybe_tag()
)
);
}
inline void initialize_converter()
{
static empty_tag_to_python cv;
}
template <class Def, class F, class Iter, class End, class Keywords>
void def_combination_aux(
Def def, F f, Iter, End, Keywords const& keywords)
{
typedef typename mpl::deref<Iter>::type spec;
initialize_converter();
typedef typename mpl::and_<
typename spec::optimized_default
, mpl::not_<typename spec::required>
>::type optimized_default;
def_combination_aux0(
def, f, Iter(), End(), keywords, optimized_default()
);
}
template <class Def, class F, class End, class Keywords>
void def_combination_aux(
Def def, F f, End, End, Keywords const& keywords)
{
def(f, keywords);
}
template <class Def, class F, class End>
void def_combination_aux(
Def def, F f, End, End, no_keywords const&)
{
def(f);
}
template <
class Def, class Specs, class Bits, class Invoker
>
void def_combination(
Def def, Specs*, Bits, Invoker*)
{
typedef typename mpl::fold<
Specs
, mpl::pair<mpl::vector0<>, Bits>
, combinations_op<mpl::_2, mpl::_1>
>::type combination0;
typedef typename combination0::first combination;
typedef typename mpl::apply_wrap1<
Invoker, combination
>::type invoker;
def_combination_aux(
def
, &invoker::execute
, typename mpl::begin<combination>::type()
, typename mpl::end<combination>::type()
, no_keywords()
);
}
template <
class Def, class Specs, class Bits, class End, class Invoker
>
void def_combinations(
Def def, Specs*, Bits, End, Invoker*)
{
def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
def_combinations(
def
, (Specs*)0
, mpl::long_<Bits::value + 1>()
, End()
, (Invoker*)0
);
}
template <
class Def, class Specs, class End, class Invoker
>
void def_combinations(
Def, Specs*, End, End, Invoker*)
{}
template <class Class>
struct def_class
{
def_class(Class& cl, char const* name)
: cl(cl)
, name(name)
{}
template <class F>
void operator()(F f) const
{
cl.def(name, f);
}
template <class F, class Keywords>
void operator()(F f, Keywords const& keywords) const
{
cl.def(name, f, keywords);
}
Class& cl;
char const* name;
};
template <class Class>
struct def_init
{
def_init(Class& cl)
: cl(cl)
{}
template <class F>
void operator()(F f) const
{
cl.def(
"__init__"
, boost::python::make_constructor(f)
);
}
template <class F, class Keywords>
void operator()(F f, Keywords const& keywords) const
{
cl.def(
"__init__"
, boost::python::make_constructor(
f, boost::python::default_call_policies(), keywords
)
);
}
Class& cl;
};
struct def_function
{
def_function(char const* name)
: name(name)
{}
template <class F>
void operator()(F f) const
{
boost::python::def(name, f);
}
template <class F, class Keywords>
void operator()(F f, Keywords const& keywords) const
{
boost::python::def(name, f, keywords);
}
char const* name;
};
} // namespace aux
template <class M, class Signature>
void def(char const* name, Signature)
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<Signature>::type
>::type
, typename mpl::end<Signature>::type
> arg_types;
typedef typename mpl::transform<
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
>::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(
aux::def_function(name)
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_invoker<M, result_type>*)0
);
}
template <class M, class Class, class Signature>
void def(Class& cl, char const* name, Signature)
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<Signature>::type
>::type
, typename mpl::end<Signature>::type
> arg_types;
typedef typename mpl::transform<
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
>::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(
aux::def_class<Class>(cl, name)
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_invoker<M, result_type>*)0
);
}
namespace aux
{
template <class K>
struct keyword
{
typedef K type;
};
template <class K>
struct keyword<K*>
: keyword<K>
{};
template <class K>
struct required
{
typedef mpl::true_ type;
};
template <class K>
struct required<K*>
{
typedef mpl::false_ type;
};
template <class K>
struct optimized
{
typedef mpl::true_ type;
};
template <class K>
struct optimized<K**>
{
typedef mpl::false_ type;
};
template <class K, class T>
struct make_kw_spec
{
typedef arg_spec<
typename keyword<K>::type
, typename required<K>::type
, typename optimized<K>::type
, T
> type;
};
} // namespace aux
template <class Keywords, class Signature>
struct init
: boost::python::def_visitor<init<Keywords, Signature> >
{
template <class Class>
void visit(Class& cl) const
{
typedef typename mpl::transform<
Keywords
, Signature
, aux::make_kw_spec<mpl::_1, mpl::_2>
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
>::type optional_arity;
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
aux::def_combinations(
aux::def_init<Class>(cl)
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_init_invoker<typename Class::wrapped_type>*)0
);
}
};
template <class Keywords, class Signature>
struct call
: boost::python::def_visitor<call<Keywords, Signature> >
{
template <class Class>
void visit(Class& cl) const
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<Signature>::type
>::type
, typename mpl::end<Signature>::type
> arg_types;
typedef typename mpl::transform<
Keywords
, arg_types
, aux::make_kw_spec<mpl::_1, mpl::_2>
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_1>
>::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(
aux::def_class<Class>(cl, "__call__")
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
);
}
};
}}} // namespace boost::parameter::python
#endif // BOOST_PARAMETER_GENERAL_051210_HPP

View File

@@ -0,0 +1,94 @@
// Copyright Daniel Wallin 2005. 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_MAKE_FUNCTION_051130_HPP
# define BOOST_PARAMETER_MAKE_FUNCTION_051130_HPP
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/python/args.hpp>
#include <boost/python/make_function.hpp>
#include <boost/python/default_call_policies.hpp>
namespace boost { namespace parameter { namespace python {
namespace detail
{
// Used as start value in the recursive arg() composition below.
struct no_keywords
{
template <class T>
T const& operator,(T const& x) const
{
return x;
}
};
template <class T, class Iter, class End, class Keywords, class K>
boost::python::object make_function_aux0(
T* p, Iter, End e, Keywords const& keywords, mpl::pair<mpl::true_,K>)
{
return make_function_aux(
p, typename mpl::next<Iter>::type(), e
, (
keywords, boost::python::arg(K::keyword())
)
);
}
template <class T, class Iter, class End, class Keywords, class K>
boost::python::object make_function_aux0(
T* p, Iter, End e, Keywords const& keywords, mpl::pair<mpl::false_,K>)
{
return make_function_aux(
p, typename mpl::next<Iter>::type(), e
, (
keywords, boost::python::arg(K::keyword()) = T::default_(K())
)
);
}
template <class T, class Iter, class End, class Keywords>
boost::python::object make_function_aux(
T* p, Iter i, End e, Keywords const& keywords)
{
return make_function_aux0(
p, i, e, keywords, typename mpl::deref<Iter>::type()
);
}
template <class T, class End, class Keywords>
boost::python::object make_function_aux(
T*, End, End, Keywords const& keywords)
{
return boost::python::make_function(
T()
, boost::python::default_call_policies()
, keywords
, typename T::signature()
);
}
} // namespace detail
template <class T>
boost::python::object make_function()
{
typedef typename T::keywords keywords;
return detail::make_function_aux(
(T*)0
, typename mpl::begin<keywords>::type()
, typename mpl::end<keywords>::type()
, detail::no_keywords()
);
}
}}} // namespace boost::parameter::python
#endif // BOOST_PARAMETER_MAKE_FUNCTION_051130_HPP

View File

@@ -1,12 +1,9 @@
<!-- Copyright David Abrahams 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) -->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatically loading index page... if nothing happens, please go to
<a href="doc/html/index.html">doc/html/index.html</a>.
<a href="doc/index.html">doc/html/index.html</a>.
</body>
</html>

View File

@@ -1,7 +1,3 @@
# 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
subproject libs/parameter/test ;
@@ -16,28 +12,8 @@ test-suite "parameter"
[ 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 ]
[ compile normalized_argument_types.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,7 +1,3 @@
# 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
project boost/parameter
@@ -13,17 +9,10 @@ test-suite "parameter"
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run unnamed.cpp ]
[ run earwicker.cpp ]
[ run tutorial.cpp ]
[ run singular.cpp ]
[ run earwicker.cpp ]
[ run mpl.cpp ]
[ run preprocessor.cpp ]
[ run efficiency.cpp : : : : : <variant>release ]
[ run maybe.cpp ]
[ compile ntp.cpp ]
[ run efficiency.cpp : : : <variant>release ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
[ compile-fail unnamed_fail.cpp ]
[ compile compose.cpp ]
;

View File

@@ -107,7 +107,6 @@ int main()
#endif
//f(index = 56, name = 55); // won't compile
return 0;
}

View File

@@ -8,10 +8,12 @@
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <cstring>
namespace test {
@@ -44,14 +46,12 @@ inline bool equal(T const& x, T const& y)
inline bool equal(char const* s1, char const* s2)
{
using namespace std;
return !strcmp(s1,s2);
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
inline bool equal(char* s1, char* s2)
{
using namespace std;
return !strcmp(s1,s2);
}
#endif

View File

@@ -1,43 +0,0 @@
//~ Copyright Rene Rivera 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>
namespace param
{
BOOST_PARAMETER_KEYWORD(Tag,a0)
BOOST_PARAMETER_KEYWORD(Tag,a1)
BOOST_PARAMETER_KEYWORD(Tag,a2)
}
namespace test
{
struct A
{
int i;
int j;
template <typename ArgPack> A(ArgPack const & args)
{
i = args[param::a0];
j = args[param::a1];
}
};
struct B : A
{
template <typename ArgPack> B(ArgPack const & args)
: A((args, param::a0 = 1))
{
}
};
}
int main()
{
test::A a((param::a0 = 1, param::a1 = 13, param::a2 = 6));
test::B b0((param::a1 = 13));
test::B b1((param::a1 = 13, param::a2 = 6));
}

View File

@@ -16,7 +16,7 @@ int main()
{
using namespace test;
f((name = 1, value = 1, test::index = 1, tester = 1,
f((name = 1, value = 1, index = 1, tester = 1,
value = 1 // repeated keyword: should not compile
));
return 0;

View File

@@ -45,11 +45,7 @@ namespace test
struct plain_weight_running_total
{
plain_weight_running_total()
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
: sum(T())
#else
: sum()
#endif
: sum(0)
{}
void operator()(T w)
@@ -68,11 +64,7 @@ namespace test
struct named_param_weight_running_total
{
named_param_weight_running_total()
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
: sum(T())
#else
: sum()
#endif
: sum(0)
{}
template <class ArgumentPack>
@@ -93,7 +85,7 @@ namespace test
// Call objects of the given Accumulator type repeatedly with x as
// an argument.
template <class Accumulator, class Arg>
void hammer(Arg const& x, long const repeats)
void hammer(Arg const& x)
{
// Strategy: because the sum in an accumulator after each call
// depends on the previous value of the sum, the CPU's pipeline
@@ -120,7 +112,7 @@ namespace test
Accumulator a[number_of_accumulators];
for (long iteration = 0; iteration < repeats; ++iteration)
for (long iteration = 0; iteration < 1000000; ++iteration)
{
for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
{
@@ -139,19 +131,19 @@ namespace test
// Measure the time required to hammer accumulators of the given
// type with the argument x.
template <class Accumulator, class T>
double measure(T const& x, long const repeats)
double measure(T const& x)
{
// Hammer accumulators a couple of times to ensure the
// instruction cache is full of our test code, and that we don't
// measure the cost of a page fault for accessing the data page
// containing the memory where the accumulators will be
// allocated
hammer<Accumulator>(x, repeats);
hammer<Accumulator>(x, repeats);
hammer<Accumulator>(x);
hammer<Accumulator>(x);
// Now start a timer
boost::timer time;
hammer<Accumulator>(x, repeats); // This time, we'll measure
hammer<Accumulator>(x); // This time, we'll measure
return time.elapsed();
}
}
@@ -159,32 +151,16 @@ namespace test
int main()
{
using namespace test;
// first decide how many repetitions to measure
long repeats = 100;
double measured = 0;
while (measured < 1.0 && repeats <= 10000000)
{
repeats *= 10;
boost::timer time;
hammer<plain_weight_running_total<double> >(.1, repeats);
hammer<named_param_weight_running_total<double> >(
(weight = .1, value = .2), repeats);
measured = time.elapsed();
}
std::cout
<< "plain time: "
<< measure<plain_weight_running_total<double> >(.1, repeats)
<< measure<plain_weight_running_total<double> >(.1)
<< std::endl;
std::cout
<< "named parameter time: "
<< measure<named_param_weight_running_total<double> >(
(weight = .1, value = .2), repeats
(weight = .1, value = .2)
)
<< std::endl;

View File

@@ -1,34 +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/keyword.hpp>
#include <boost/parameter/aux_/maybe.hpp>
#include <cassert>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, kw)
BOOST_PARAMETER_KEYWORD(tag, unused)
template <class Args>
int f(Args const& args)
{
return args[kw | 1.f];
}
} // namespace test
int main()
{
using test::kw;
using test::unused;
using test::f;
using boost::parameter::aux::maybe;
assert(f((kw = 0, unused = 0)) == 0);
assert(f(unused = 0) == 1);
assert(f((kw = maybe<int>(), unused = 0)) == 1);
assert(f((kw = maybe<int>(2), unused = 0)) == 2);
}

View File

@@ -65,6 +65,7 @@ namespace test
f_impl<Expected>(f_parameters()(t, name_));
}
void run()
{
typedef test::tag::tester tester_;
@@ -76,7 +77,6 @@ namespace test
f<mpl::list3<tester_,name_,index_> >(1, 2, index = 3);
f<mpl::list3<tester_,name_,index_> >(1, index = 2, name = 3);
f<mpl::list2<name_,value_> >(name = 3, value = 4);
f_impl<mpl::list1<value_> >(value = 4);
}
}

View File

@@ -1,83 +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.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 const>));
BOOST_MPL_ASSERT((boost::is_same<y_type,int const>));
return 0;
}
BOOST_PARAMETER_FUNCTION((int), g, tag,
(required
(x, (count_instances))
)
)
{
assert(count_instances::count == 1);
return 0;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(x, (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

@@ -1,109 +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.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
namespace mpl = boost::mpl;
namespace parameter = boost::parameter;
template <class T = int>
struct a0_is
: parameter::template_keyword<a0_is<>, T>
{};
template <class T = int>
struct a1_is
: parameter::template_keyword<a1_is<>, T>
{};
template <class T = int>
struct a2_is
: parameter::template_keyword<a2_is<>, T>
{};
template <class T = int>
struct a3_is
: parameter::template_keyword<a3_is<>, T>
{};
struct X {};
struct Y : X {};
template <
class A0 = parameter::void_
, class A1 = parameter::void_
, class A2 = parameter::void_
, class A3 = parameter::void_
>
struct with_ntp
{
typedef typename parameter::parameters<
a0_is<>, a1_is<>, a2_is<>
, parameter::unnamed<
a3_is<>, boost::is_base_and_derived<X, mpl::_>
>
>::bind<A0,A1,A2,A3
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, parameter::void_
#endif
>::type args;
typedef typename parameter::binding<
args, a0_is<>, void*
>::type a0;
typedef typename parameter::binding<
args, a1_is<>, void*
>::type a1;
typedef typename parameter::binding<
args, a2_is<>, void*
>::type a2;
typedef typename parameter::binding<
args, a3_is<>, void*
>::type a3;
typedef void(*type)(a0,a1,a2,a3);
};
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<>::type, void(*)(void*,void*,void*,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<a2_is<int> >::type, void(*)(void*,void*,int,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<a1_is<int> >::type, void(*)(void*,int,void*,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<a2_is<int const>, a1_is<float> >::type, void(*)(void*,float,int const,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int const>::type, void(*)(int const, void*, void*,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int, float>::type, void(*)(int, float, void*,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int, float, char>::type, void(*)(int, float, char,void*)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<Y>::type, void(*)(void*,void*,void*, Y)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int&, Y, a2_is<char> >::type, void(*)(int&,void*,char, Y)
>));

View File

@@ -1,394 +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/type_traits/is_const.hpp>
#include <string>
#include "basics.hpp"
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
#endif
namespace test {
BOOST_PARAMETER_BASIC_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *)
(out(index), (int))
)
)
{
typedef typename boost::parameter::binding<
Args, tag::index, int&
>::type index_type;
BOOST_MPL_ASSERT((boost::is_same<index_type, int&>));
args[tester](
args[name]
, args[value | 1.f]
, args[index | 2]
);
return 1;
}
BOOST_PARAMETER_BASIC_FUNCTION((int), g, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *)
(out(index), (int))
)
)
{
typedef typename boost::parameter::binding<
Args, tag::index, int const&
>::type index_type;
BOOST_MPL_ASSERT((boost::is_same<index_type, int const&>));
args[tester](
args[name]
, args[value | 1.f]
, args[index | 2]
);
return 1;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *, 1.f)
(out(index), (int), 2)
)
)
{
BOOST_MPL_ASSERT((boost::is_same<index_type, int const>));
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_MPL_ASSERT((boost::is_same<index_type, int const>));
# endif
tester(
name
, value
, index
);
return 1;
}
struct base
{
template <class Args>
base(Args const& args)
{
args[tester](
args[name]
, args[value | 1.f]
, args[index | 2]
);
}
};
struct class_ : base
{
BOOST_PARAMETER_CONSTRUCTOR(class_, (base), tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *)
(index, *)
)
)
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *)
(index, *)
)
)
{
args[tester](
args[name]
, args[value | 1.f]
, args[index | 2]
);
return 1;
}
BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, tag,
(required
(tester, *)
(name, *)
)
(optional
(value, *)
(index, *)
)
)
{
args[tester](
args[name]
, args[value | 1.f]
, args[index | 2]
);
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(
(int), sfinae, tag,
(required
(name, (std::string))
)
)
{
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
BOOST_PARAMETER_FUNCTION(
(int), sfinae1, tag,
(required
(name, *(boost::is_convertible<boost::mpl::_, std::string>))
)
)
{
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
sfinae1(A0 const& a0)
{
return 0;
}
#endif
}
int main()
{
using namespace test;
f(
tester = values(S("foo"), 1.f, 2)
, S("foo")
);
f(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
int index_lvalue = 2;
f(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, 1.f
, index_lvalue
);
g(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, 1.f
, 2
);
h(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, 1.f
, 2
);
h2(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
, 1.f
);
class_ x(
tester = values(S("foo"), 1.f, 2)
, S("foo"), test::index = 2
);
x.f(
tester = values(S("foo"), 1.f, 2)
, S("foo")
);
x.f(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
x.f2(
tester = 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)
, S("foo")
);
x_const.f(
tester = values(S("foo"), 1.f, 2)
, name = S("foo")
);
x_const.f2(
tester = 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(
tester = 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);
assert(sfinae1("foo") == 1);
assert(sfinae1(1) == 0);
#endif
return 0;
}

View File

@@ -1,159 +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>
#include <boost/utility/enable_if.hpp>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
BOOST_PARAMETER_KEYWORD(tag, 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), tag,
(optional
(x, *)
(y, *)
)
)
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag,
(required
(x, *)
(y, *)
)
(optional
(z, *)
)
)
{
return args[x] + args[y] + args[z | 0];
}
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((std::string), g, tag,
(optional
(x, *)
(y, *)
)
)
{
return std::string(args[x | "foo"]) + args[y | "bar"];
}
BOOST_PARAMETER_MEMBER_FUNCTION((X&), h, tag,
(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, 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_parameter)
{
namespace mpl = boost::mpl;
using namespace test;
using namespace boost::python;
class_<X>("X")
.def(
boost::parameter::python::init<
mpl::vector<
tag::x*(std::string), tag::y*(std::string)
>
>()
)
.def(
"f"
, boost::parameter::python::function<
f_fwd
, mpl::vector<
int, tag::x(int), tag::y(int), tag::z*(int)
>
>()
)
.def(
"g"
, boost::parameter::python::function<
g_fwd
, mpl::vector<
std::string, tag::x*(std::string), tag::y*(std::string)
>
>()
)
.def(
"h"
, boost::parameter::python::function<
h_fwd
, mpl::vector<
X&, tag::x*(std::string), tag::y*(std::string)
>
>()
, return_arg<>()
)
.def(
boost::parameter::python::call<
mpl::vector<
X&, tag::x(int)
>
>() [ return_arg<>() ]
)
.def_readonly("value", &X::value);
}

View File

@@ -1,41 +0,0 @@
# 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_parameter 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
return doctest.testmod(python)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

38
test/python/Jamfile Executable file
View File

@@ -0,0 +1,38 @@
subproject libs/parameter/test/python ;
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
STATS_ROOT ?= $(BOOST_ROOT) ;
extension parameter
: simple.cpp
<template>@boost/libs/python/build/extension
;
boost-python-runtest test1
: test_simple.py
<pyd>parameter
;
extension general
: general.cpp
<template>@boost/libs/python/build/extension
;
boost-python-runtest test2
: test_general.py
<pyd>general
;
extension accumulator_set
: accumulator.cpp
<template>@boost/libs/python/build/extension
: <include>$(STATS_ROOT)
;
boost-python-runtest test3
: test_accumulator.py
<pyd>accumulator_set
;

97
test/python/accumulator.cpp Executable file
View File

@@ -0,0 +1,97 @@
// Copyright Daniel Wallin 2005. 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 <iostream>
#include <boost/python.hpp>
#include <boost/parameter/python/general.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/weighted_mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/order.hpp>
#include <boost/accumulators/statistics/order_variate.hpp>
#include <boost/accumulators/statistics/with_error.hpp>
#include <boost/accumulators/framework/parameters/weights.hpp>
#include <boost/accumulators/statistics/variates/covariate.hpp>
using namespace boost;
using namespace boost::accumulators;
typedef accumulator_set<
double
, stats<tag::order_variate<int, tag::covariate1> >
> accumulator_type;
template<typename Range>
python::list listify_range(Range const &range)
{
python::list l;
typedef typename boost::range_result_iterator<Range>::type iterator;
iterator begin = range.begin();
iterator end = range.end();
for(; begin != end; ++begin)
l.append(*begin);
return l;
}
python::list listify_covariate1(accumulator_type const& acc)
{
return listify_range(order_variate<int, tag::covariate1>(acc));
}
namespace boost { namespace accumulators { namespace tag
{
char const* keyword_name(sample*)
{
return "sample";
}
char const* keyword_name(covariate1*)
{
return "covariate1";
}
}}} // namespace boost::accumulators::tag
namespace boost { namespace accumulators { namespace detail
{
char const* keyword_name(cache_size_tag*)
{
return "cache_size";
}
}}} // namespace boost::accumulators::detail
BOOST_PYTHON_MODULE(accumulator_set)
{
using namespace boost::python;
namespace py = boost::parameter::python;
class_<accumulator_type>("accumulator_set", no_init)
.def(
py::init<
mpl::vector1<
accumulators::detail::cache_size_tag
>
, mpl::vector1<unsigned>
>()
)
.def(
py::call<
mpl::vector2<
tag::sample
, tag::covariate1
>
, mpl::vector3<void, double, int>
>()
);
def("covariate1", listify_covariate1);
}

100
test/python/general.cpp Executable file
View File

@@ -0,0 +1,100 @@
// Copyright Daniel Wallin 2005. 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/python/general.hpp>
#include <boost/parameter/parameters.hpp>
namespace mpl = boost::mpl;
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
BOOST_PARAMETER_KEYWORD(tag, z)
struct tag::x
{
static char const* keyword()
{
return "x";
}
};
struct tag::y
{
static char const* keyword()
{
return "y";
}
};
struct tag::z
{
static char const* keyword()
{
return "z";
}
};
typedef boost::parameter::parameters<
tag::x
, tag::y
> f_parameters;
template <class Args>
float f_impl(Args const& args)
{
return args[x | 1] / args[y | 1];
}
template <class A0>
float f(A0 const& a0)
{
return f_impl(f_parameters()(a0));
}
template <class A0, class A1>
float f(A0 const& a0, A1 const& a1)
{
return f_impl(f_parameters()(a0,a1));
}
template <class A0, class A1, class A2>
float f(A0 const& a0, A1 const& a1, A2 const& a2)
{
return f_impl(f_parameters()(a0,a1,a2));
}
struct meta
{
typedef mpl::vector3<
mpl::pair<tag::x, mpl::true_>
, mpl::pair<tag::y, mpl::false_>
, mpl::pair<tag::z, mpl::false_>
> keywords;
template <class R, class A0>
R operator()(boost::type<R>, A0 const& a0)
{
return f(a0);
}
template <class R, class A0, class A1>
R operator()(boost::type<R>, A0 const& a0, A1 const& a1)
{
return f(a0,a1);
}
template <class R, class A0, class A1, class A2>
R operator()(boost::type<R>, A0 const& a0, A1 const& a1, A2 const& a2)
{
return f(a0,a1,a2);
}
};
BOOST_PYTHON_MODULE(general)
{
boost::parameter::python::def<meta>("f", mpl::vector4<float,float,float,float>());
}

26
test/python/simple.cpp Executable file
View File

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin 2005. 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 <iostream>
#include "simple.hpp"
int add(int x, int y, int z, int u)
{
return x + y + z + u;
}
void print(int value, char const* name, float scale)
{
std::cout << "value = " << value << "\n";
std::cout << "name = " << name << "\n";
std::cout << "scale = " << scale << "\n";
}
BOOST_PYTHON_MODULE(parameter)
{
def("add", boost::parameter::python::make_function<add_meta>());
def("echo", boost::parameter::python::make_function<print_meta>());
}

42
test/python/simple.hpp Executable file
View File

@@ -0,0 +1,42 @@
// Copyright Daniel Wallin 2005. 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_SIMPLE_051130_HPP
# define BOOST_PARAMETER_SIMPLE_051130_HPP
# include <boost/parameter/python/function.hpp>
# include <boost/parameter/python/make_function.hpp>
ZKB_KEYWORD(tag, x)
ZKB_KEYWORD(tag, y)
ZKB_KEYWORD(tag, z)
ZKB_KEYWORD(tag, u)
ZKB_FUNCTION(int, add, add_meta, tag,
(required
(x, int)
(y, int)
)
(optional
(z, int, 0)
(u, int, 0)
)
);
ZKB_KEYWORD(tag, value)
ZKB_KEYWORD(tag, name)
ZKB_KEYWORD(tag, scale)
ZKB_FUNCTION(void, print, print_meta, tag,
(required
(value, int)
)
(optional
(name, char const*, "unnamed")
(scale, float, 1.f)
)
);
#endif // BOOST_PARAMETER_SIMPLE_051130_HPP

View File

@@ -0,0 +1,39 @@
'''
>>> import accumulator_set
>>> acc = accumulator_set.accumulator_set(cache_size = 4)
>>> acc(2.1, covariate1 = 21)
>>> acc(1.1, covariate1 = 11)
>>> acc(2.1, covariate1 = 21)
>>> acc(1.1, covariate1 = 11)
>>> accumulator_set.covariate1(acc)
[21, 21, 11, 11]
>>> acc(21.1, covariate1 = 211)
>>> acc(11.1, covariate1 = 111)
>>> acc(21.1, covariate1 = 211)
>>> acc(11.1, covariate1 = 111)
>>> accumulator_set.covariate1(acc)
[211, 211, 111, 111]
>>> acc(42.1, covariate1 = 421)
>>> acc(41.1, covariate1 = 411)
>>> acc(42.1, covariate1 = 421)
>>> acc(41.1, covariate1 = 411)
>>> accumulator_set.covariate1(acc)
[421, 421, 411, 411]
>>> acc(32.1, covariate1 = 321)
>>> acc(31.1, covariate1 = 311)
>>> acc(32.1, covariate1 = 321)
>>> acc(31.1, covariate1 = 311)
>>> accumulator_set.covariate1(acc)
[421, 421, 411, 411]
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_accumulator
return doctest.testmod(test_accumulator)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -0,0 +1,25 @@
r'''>>> import general
>>> general.f(1)
1.0
>>> general.f(x=2)
2.0
>>> general.f(1,y=2)
0.5
>>> general.f(x=4,z=2)
4.0
>>> general.f(y=2,x=4)
2.0
>>> general.f(z=0,y=2,x=4)
2.0
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_general
return doctest.testmod(test_general)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -0,0 +1,21 @@
r'''>>> import parameter
>>> parameter.add(1,2)
3
>>> parameter.add(x=1,y=2)
3
>>> parameter.add(1,2,z=3)
6
>>> parameter.add(x=1,y=2,z=3,u=4)
10
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_simple
return doctest.testmod(test_simple)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -54,6 +54,8 @@ namespace test
f_impl(f_parameters()());
}
using boost::parameter::aux::void_;
template<class A0>
void f(
A0 const& a0

View File

@@ -1,42 +0,0 @@
// Copyright Daniel Wallin 2005. 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/keyword.hpp>
#include <boost/detail/lightweight_test.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
struct default_src
{
typedef int result_type;
int operator()() const
{
return 0;
}
};
template <class ArgumentPack, class K, class T>
void check(ArgumentPack const& p, K const& kw, T const& value)
{
BOOST_TEST(p[kw] == value);
}
int main()
{
check(x = 20, x, 20);
check(y = 20, y, 20);
check(x = 20, x | 0, 20);
check(y = 20, y | 0, 20);
check(x = 20, x | default_src(), 20);
check(y = 20, y | default_src(), 20);
check(y = 20, x | 0, 0);
check(y = 20, x || default_src(), 0);
return boost::report_errors();
}

View File

@@ -3,6 +3,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <ostream>
#include <boost/parameter/keyword.hpp>
namespace graphs

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;
}