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
82 changed files with 3590 additions and 11297 deletions

View File

@@ -1,29 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#----------------------------------------------------------------------------
# This file was automatically generated from the original CMakeLists.txt file
# Add a variable to hold the headers for the library
set (lib_headers
parameter.hpp
parameter
)
# Add a library target to the build system
boost_library_project(
parameter
# SRCDIRS
TESTDIRS test
HEADERS ${lib_headers}
# DOCDIRS
DESCRIPTION "Write functions that accept arguments by name."
MODULARIZED
AUTHORS "David Abrahams <dave -at- boostpro.com>"
"Daniel Wallin <dalwan01 -at- student.umu.se>"
# MAINTAINERS
)

5
doc/Jamfile.v2 Normal file → Executable file
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)
;
}

2647
doc/html/index.html Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

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

731
doc/html/reference.html Normal file → Executable file

File diff suppressed because it is too large Load Diff

15
doc/html/rst.css Normal file → Executable file
View File

@@ -1,8 +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 "../../../../rst.css";
div.section div.section div.section dl {
@@ -18,16 +13,6 @@ img {
vertical-align: middle
}
span.vellipsis {
display: block;
width: 5px;
height: 22px;
background: url("vellipsis.gif");
margin-left: 3em;
text-indent: -1000px;
}
PRE
{
FONT-FAMILY: monospace ;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 B

2866
doc/index.rst Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,778 +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. This is needed because ``window::open()``
is a function template, so we can't refer to it in any other way.
::
struct open_fwd
{
template <class A0, class A1, class A2>
void operator()(
boost::type<void>, window& self
, A0 const& a0, A1 const& a1, A2 const& a2
)
{
self.open(a0, a1, a2);
}
};
The first parameter, ``boost::type<void>``, tells the forwarding overload
what the return type should be. In this case we know that it's always void
but in some cases, when we are exporting several specializations of a
Boost.Parameter-enabled template, we need to use that parameter to
deduce the return type.
``window::open()`` takes a total of 3 parameters, so the forwarding function
needs to take three parameters as well.
.. Note::
We only need one overload in the forwarding class, despite the
fact that there are two optional parameters. There are special
circumstances when several overload are needed; see
`special keywords`_.
Next we'll define the module and export the class:
::
BOOST_PYTHON_MODULE(my_module)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<window>("window")
.def(
"open", py::function<
open_fwd
, mpl::vector<
void
, tag::title(std::string)
, tag::width*(unsigned)
, tag::height*(unsigned)
>
>()
);
}
.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
, howmany = 'all'
)
.. @del jam_prefix[:]
``py::function`` is passed two parameters. The first one is the class with
forwarding overloads that we defined earlier. The second one is an `MPL
Sequence`_ with the keyword tag types and argument types for the function
specified as function types. The pointer syntax used in ``tag::width*`` and
``tag::height*`` means that the parameter is optional. The first element of
the `MPL Sequence`_ is the return type of the function, in this case ``void``,
which is passed as the first argument to ``operator()`` in the forwarding
class.
.. The
pointer syntax means that the parameter is optional, so in this case
``width`` and ``height`` are optional parameters. The third parameter
is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
then the parameter types:
.. parsed-literal::
mpl::vector<void, std::string, unsigned, unsigned>
*return type* *title* *width* *height*
.. @ignore()
That's it! This class can now be used in Python with the expected syntax::
>>> w = my_module.window()
>>> w.open(title = "foo", height = 20)
.. @example.prepend('import my_module')
.. @run_python(module_path = my_module)
.. Sorry to say this at such a late date, but this syntax really
.. strikes me as cumbersome. Couldn't we do something like:
class_<window>("window")
.def(
"open",
(void (*)(
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned))
)0
);
or at least:
class_<window>("window")
.def(
"open",
mpl::vector<
void,
tag::title(std::string),
tag::width*(unsigned),
tag::height*(unsigned)
>()
);
assuming, that is, that we will have to repeat the tags (yes,
users of broken compilers will have to give us function pointer
types instead).
------------------------------------------------------------------------------
concept |ParameterSpec|
-----------------------
A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag,
``K``, and the argument type, ``T``, for a parameter.
``K`` is either:
* A *required* keyword of the form ``Tag``
* **or**, an *optional* keyword of the form ``Tag*``
* **or**, a *special* keyword of the form ``Tag**``
where ``Tag`` is a keyword tag type, as used in a specialization
of |keyword|__.
.. |keyword| replace:: ``boost::parameter::keyword``
__ ../../../parameter/doc/html/reference.html#keyword
The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is
defined as the closed range:
.. parsed-literal::
[ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ]
For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``,
the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the
**arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``.
*special* keywords
---------------------------------
Sometimes it is desirable to have a default value for a parameter that differ
in type from the parameter. This technique is useful for doing simple tag-dispatching
based on the presence of a parameter. For example:
.. An example_ of this is given in the Boost.Parameter
docs. The example uses a different technique, but could also have been written like this:
.. parsed-literal::
namespace core
{
template <class ArgumentPack>
void dfs_dispatch(ArgumentPack const& args, mpl::false\_)
{
*…compute and use default color map…*
}
template <class ArgumentPack, class ColorMap>
void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
{
*…use colormap…*
}
}
template <class ArgumentPack>
void depth_first_search(ArgumentPack const& args)
{
core::dfs_dispatch(args, args[color | mpl::false_()]);
}
.. @example.prepend('''
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/mpl/bool.hpp>
#include <cassert>
BOOST_PARAMETER_KEYWORD(tag, color);
typedef boost::parameter::parameters<tag::color> params;
namespace mpl = boost::mpl;
''')
.. @example.replace_emphasis('''
assert(args[color | 1] == 1);
''')
.. @example.replace_emphasis('''
assert(args[color | 1] == 0);
''')
.. @example.append('''
int main()
{
depth_first_search(params()());
depth_first_search(params()(color = 0));
}''')
.. @build()
.. .. _example: index.html#dispatching-based-on-the-presence-of-a-default
In the above example the type of the default for ``color`` is ``mpl::false_``, a
type that is distinct from any color map that the user might supply.
When binding the case outlined above, the default type for ``color`` will not
be convertible to the parameter type. Therefore we need to tag the ``color``
keyword as a *special* keyword. This is done by specifying the tag as
``tag::color**`` when binding the function (see `concept ParameterSpec`_ for
more details on the tagging). By doing this we tell the binding functions that
it needs to generate two overloads, one with the ``color`` parameter present
and one without. Had there been two *special* keywords, four overloads would
need to be generated. The number of generated overloads is equal to 2\
:sup:`N`, where ``N`` is the number of *special* keywords.
------------------------------------------------------------------------------
class template ``init``
-----------------------
Defines a named parameter enabled constructor.
.. parsed-literal::
template <class ParameterSpecs>
struct init : python::def_visitor<init<ParameterSpecs> >
{
template <class Class>
void def(Class& class\_);
template <class CallPolicies>
*def\_visitor* operator[](CallPolicies const& policies) const;
};
.. @ignore()
``init`` requirements
~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element is a
model of |ParameterSpec|.
* For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity
range** of ``ParameterSpecs``, ``Class`` must support these
expressions:
======================= ============= =========================================
Expression Return type Requirements
======================= ============= =========================================
``Class(a0, …, aN)`` \- ``a0``\ …\ ``aN`` are tagged arguments.
======================= ============= =========================================
``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.
Example
~~~~~~~
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
struct base
{
template <class ArgumentPack>
base(ArgumentPack const& args)
{
*… use args …*
}
};
class X : base
{
public:
BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
(required (x, \*))
(optional (y, \*))
)
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<X>("X", no_init)
.def(
py::init<
mpl::vector<tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
''')
.. @example.replace_emphasis('my_module')
.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
class template ``call``
-----------------------
Defines a ``__call__`` operator, mapped to ``operator()`` in C++.
.. parsed-literal::
template <class ParameterSpecs>
struct call : python::def_visitor<call<ParameterSpecs> >
{
template <class Class>
void def(Class& class\_);
template <class CallPolicies>
*def\_visitor* operator[](CallPolicies const& policies) const;
};
.. @ignore()
``call`` requirements
~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``c(…)``.
* ``Class`` must support these expressions, where ``c`` is an
instance of ``Class``:
=================== ==================== =======================================
Expression Return type Requirements
=================== ==================== =======================================
``c(a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
=================== ==================== =======================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.
Example
~~~~~~~
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
namespace parameter = boost::parameter;
typedef parameter::parameters<
parameter::required<tag::x>
, parameter::optional<tag::y>
> call_parameters;
class X
{
public:
template <class ArgumentPack>
int call_impl(ArgumentPack const& args)
{
*… use args …*
}
template <class A0>
int operator()(A0 const& a0)
{
return call_impl(call_parameters()(a0));
}
template <class A0, class A1>
int operator()(A0 const& a0, A1 const& a1)
{
return call_impl(call_parameters()(a0,a1));
}
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = parameter::python;
namespace mpl = boost::mpl;
class_<X>("X")
.def(
py::call<
mpl::vector<int, tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(args[x] == 0);
assert(args[y | 1] == 1);
return 0;
''')
.. @example.replace_emphasis('my_module')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
class template ``function``
---------------------------
Defines a named parameter enabled member function.
.. parsed-literal::
template <class Fwd, class ParameterSpecs>
struct function : python::def_visitor<function<Fwd, ParameterSpecs> >
{
template <class Class, class Options>
void def(Class& class\_, char const* name, Options const& options);
};
.. @ignore()
``function`` requirements
~~~~~~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``c.f(…)``, where ``f`` is the member
function.
* An instance of ``Fwd`` must support this expression:
============================================ ==================== =================================================
Expression Return type Requirements
============================================ ==================== =================================================
``fwd(boost::type<R>(), self, a0, …, aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
the function should be invoked. ``a0``\ …\ ``aN``
are tagged arguments.
============================================ ==================== =================================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
Example
~~~~~~~
This example exports a member function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.
.. parsed-literal::
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/python.hpp>
#include <boost/python.hpp>
#include <boost/mpl/vector.hpp>
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
class X
{
public:
BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
(required (x, \*))
(optional (y, \*, 1))
)
{
*…*
}
};
struct f_fwd
{
template <class A0, class A1>
void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1)
{
self.f(a0, a1);
}
};
BOOST_PYTHON_MODULE(*module name*)
{
using namespace boost::python;
namespace py = boost::parameter::python;
namespace mpl = boost::mpl;
class_<X>("X")
.def("f",
py::function<
f_fwd
, mpl::vector<void, tag::x(int), tag::y\*(int)>
>()
);
}
.. @example.replace_emphasis('''
assert(x == 0);
assert(y == 1);
''')
.. @example.replace_emphasis('my_module')
.. @my_module = build(
output = 'my_module'
, target_rule = 'python-extension'
, input = '/boost/python//boost_python'
)
------------------------------------------------------------------------------
function template ``def``
-------------------------
Defines a named parameter enabled free function in the current Python scope.
.. parsed-literal::
template <class Fwd, class ParameterSpecs>
void def(char const* name);
.. @ignore()
``def`` requirements
~~~~~~~~~~~~~~~~~~~~
* ``ParameterSpecs`` is an `MPL sequence`_ where each element
except the first models |ParameterSpec|. The first element
is the result type of ``f(…)``, where ``f`` is the function.
* An instance of ``Fwd`` must support this expression:
====================================== ==================== =======================================
Expression Return type Requirements
====================================== ==================== =======================================
``fwd(boost::type<R>(), a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
====================================== ==================== =======================================
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
Example
~~~~~~~
This example exports a function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.
.. parsed-literal::
BOOST_PARAMETER_FUNCTION((void), f, tag,
(required (x, \*))
(optional (y, \*, 1))
)
{
*…*
}
struct f_fwd
{
template <class A0, class A1>
void operator()(boost::type<void>, A0 const& a0, A1 const& a1)
{
f(a0, a1);
}
};
BOOST_PYTHON_MODULE(…)
{
def<
f_fwd
, mpl::vector<
void, tag::\ x(int), tag::\ y\*(int)
>
>("f");
}
.. @ignore()
.. again, the undefined ``fwd`` identifier.
Portability
-----------
The Boost.Parameter Python binding library requires *partial template
specialization*.

367
doc/reference.rst Normal file → Executable file
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
@@ -174,7 +175,7 @@ Concepts
This section describes the generic type concepts_ used by the Parameter library.
.. _concepts: http://www.boost.org/more/generic_programming.html#concept
.. _concepts: ../../../../more/generic_programming.html#concept
|ArgumentPack|
--------------
@@ -253,7 +254,7 @@ argument type. In each row,
+----------------------+--------------+--------------------------------+
|Type |``A`` required|Condition ``A`` must satisfy |
+======================+==============+================================+
|``K`` |no |*n/a* |
||keyword|_\ ``<K>`` |no |*n/a* |
+----------------------+--------------+--------------------------------+
||optional|_\ ``<K,F>``|no |``mpl::apply<F,A>::type::value``|
| | |is ``true``. |
@@ -381,15 +382,13 @@ __ ../../../../boost/parameter/parameters.hpp
};
template <class A0>
|ArgumentPack|_ `operator()`_\(A0& a0) const;
|ArgumentPack|_ `operator()`_\(A0 const& a0) const;
template <class A0, class A1>
|ArgumentPack|_ `operator()`_\(A0& a0, A1& a1) const;
:vellipsis:`⋮`
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1) const;
:large:`⋮`
template <class A0, class A1, …class A\ β>
|ArgumentPack|_ `operator()`_\(A0& a0, A1& a1, …A\ β& a\ β) const;
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1, …A\ β const& a\ β) const;
};
@@ -402,22 +401,13 @@ __ ../../../../boost/parameter/parameters.hpp
follows, for any argument type ``A``\ *i*:
| let ``D0`` the set [d0, …, d\ *j*] of all **deduced** *parameter specs* in [``P0``, …, ``P``\ β]
| ``R``\ *i* is ``A``\ *i*\ 's |intended argument type|
|
| if ``A``\ *i* is a result type of ``keyword<T>::``\ |operator=|_
| then
| ``K``\ *i* is ``T``
| else
| if some ``A``\ *j* where *j*\ ≤\ *i* is a result type of ``keyword<T>::``\ |operator=|_
| *or* some ``P``\ *j* in *j*\ ≤\ *i* is **deduced**
| then
| if some *parameter spec* ``d``\ *j* in ``D``\ *i* matches ``A``\ *i*
| then
| ``K``\ *i* is ``d``\ *j*\ 's |keyword tag type|.
| ``D``\ :sub:`i+1` is ``D``\ *i* - [``d``\ *j*]
| else
| ``K``\ *i* is ``P``\ *i*\ 's |keyword tag type|.
| if ``A``\ *i* is a result type of ``keyword<T>::``\ |operator=|_
| then
| ``K``\ *i* is ``T``
| else
| ``K``\ *i* is ``P``\ *i*\ 's |keyword tag type|.
.. _match:
@@ -433,7 +423,7 @@ __ ../../../../boost/parameter/parameters.hpp
every *j* in 0…β, either:
* ``P``\ *j* is the *unspecified* default
* **or**, ``P``\ *j* is a *keyword tag type*
* **or**, ``P``\ *j* is a specialization of |keyword|_,
* **or**, ``P``\ *j* is |optional|_ ``<X,F>`` and either
@@ -451,10 +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:
@@ -495,23 +483,6 @@ The default value of ``Predicate`` is an unspecified |Metafunction|_ that return
.. |Metafunction| replace:: :concept:`Metafunction`
.. _Metafunction: ../../../mpl/doc/refmanual/metafunction.html
``deduced``
-----------
This template is used to wrap the *keyword tag* argument to
``optional`` or ``required``.
:Defined in: `boost/parameter/parameters.hpp`__
__ ../../../../boost/parameter/parameters.hpp
.. parsed-literal::
template <class Tag>
struct deduced;
//////////////////////////////////////////////////////////////////////////////
Metafunctions
@@ -570,37 +541,6 @@ __ ../../../../boost/parameter/binding.hpp
reference| exists, returns ``boost::``\ |result_of|_\ ``<F()>::type``. [#no_result_of]_
``value_type``
--------------
Returns the result type of indexing an argument pack with a
|keyword tag type| or with a |tagged default|.
:Defined n: `boost/parameter/value_type.hpp`__
__ ../../../../boost/parameter/value_type.hpp
.. parsed-literal::
template <class A, class K, class D = void>
struct value_type
{
typedef … type;
};
:Requires: ``A`` is a model of |ArgumentPack|_.
:Returns: the type of the |tagged reference| in ``A``
having |keyword tag type| ``K``, if any. If no such |tagged
reference| exists, returns ``D``. Equivalent to::
typename remove_reference<
typename binding<A, K, D>::type
>::type
… when ``D`` is not a reference type.
//////////////////////////////////////////////////////////////////////////////
Code Generation Macros
@@ -609,256 +549,9 @@ Code Generation Macros
Macros in this section can be used to ease the writing of code
using the Parameter libray by eliminating repetitive boilerplate.
``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``
-----------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
:Requires: ``result`` is the parenthesized return type of the function.
``name`` is the base name of the function, this is the name of the
generated forwarding functions. ``tag_namespace`` is the namespace in
which the keywords used by the function resides. ``arguments`` is
a list of *argument specifiers*, as defined below.
:Argument specifiers syntax:
.. parsed-literal::
argument-specifiers ::= *specifier-group* {*specifier-group*}
specifier-group0 ::= *specifier-group1* |
( '**(**' '**deduced**' *specifier-group1* {*specifier-group1*} '**)**' )
specifier-group1 ::= ( '**(**' '**optional**' *optional-specifier* {*optional-specifier*} '**)**' ) |
( '**(**' '**required**' *required-specifier* {*required-specifier*} '**)**' )
optional-specifier ::= '**(**' *name* '**,**' *restriction* '**,**' *default-value* ')'
required-specifier ::= '**(**' *name* '**,**' *restriction* ')'
restriction ::= ('*****' '**(**' *lambda-expression* '**)**' ) |
( '**(**' *typename* '**)**' ) |
'*****'
``name`` is any valid C++ identifier. ``default-value`` is any valid
C++ expression. ``typename`` is the name of a type.
``lambda-expression`` is an `MPL lambda expression`_.
.. _`MPL lambda expression`: ../../../mpl/doc/refmanual/lambda-expression.html
:Generated names in enclosing scope:
* ``boost_param_result_ ## __LINE__ ## name``
* ``boost_param_params_ ## __LINE__ ## name``
* ``boost_param_parameters_ ## __LINE__ ## name``
* ``boost_param_impl ## name``
* ``boost_param_default_ ## __LINE__ ## name``
Approximate expansion:
**Where**:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
template <class T>
struct boost_param_result\_ ## __LINE__ ## **name**
{
typedef **result** type;
};
struct boost_param_params\_ ## __LINE__ ## **name**
: boost::parameter::parameters<
*list of parameter specifications, based on arguments*
>
{};
typedef boost_param_params\_ ## __LINE__ ## **name**
boost_param_parameters\_ ## __LINE__ ## **name**;
template <class A0, …, class A\ **n**>
*result type* **name**\ (
A0 *cv*\ & a0, …, A\ **n** *cv*\ & a\ **n**
, typename boost_param_parameters\_ ## __LINE__ ## **name**::match<
A0 *cv*, …, A\ **n** *cv*
>::type = boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
*… forward to implementation …*
}
:vellipsis:`⋮`
template <class A0, …, class A\ **m**>
*result type* **name**\ (
A0 *cv*\ & a0, …, A\ **m** *cv*\ & a\ **m**
, typename boost_param_parameters\_ ## __LINE__ ## **name**::match<
A0 *cv*, …, A\ **m** *cv*
>::type = boost_param_parameters\_ ## __LINE__ ## **name**\ ()
)
{
*… forward to implementation …*
}
template <
class ResultType
, class *argument name*\ **0** ## _type
, class *argument name*\ **m** ## _type
>
ResultType boost_param_default\_ ## __LINE__ ## **name**\ (
(ResultType(*)())
, *argument name*\ **0** ## _type& *argument name*\ **0**
, *argument name*\ **m** ## _type& *argument name*\ **m**
)
``BOOST_PARAMETER_MEMBER_FUNCTION(result,name,tag_namespace,arguments)``
------------------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
See ``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``
``BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, arguments)``
--------------------------------------------------------------------
:Defined in: `boost/parameter/preprocessor.hpp`__
__ ../../../../boost/parameter/preprocessor.hpp
:Requires: ``cls`` is the name of this class. ``impl`` is the
parenthesized implementation base class for ``cls``.
``tag_namespace`` is the namespace in which the keywords
used by the function resides. ``arguments`` is
a list of *argument specifiers*, as defined in
``BOOST_PARAMETER_FUNCTION(result,name,tag_namespace,arguments)``.
:Generated names in enclosing scope:
* ``boost_param_params_ ## __LINE__ ## ctor``
* ``constructor_parameters ## __LINE__``
Approximate expansion:
**Where**:
* ``n`` denotes the *minimum* arity, as determined from ``arguments``.
* ``m`` denotes the *maximum* arity, as determined from ``arguments``.
.. parsed-literal::
struct boost_param_params\_ ## __LINE__ ## ctor
: boost::parameter::parameters<
*list of parameter specifications, based on arguments*
>
{};
typedef boost_param_params\_ ## __LINE__ ## **name**
constructor_parameters ## __LINE__;
template <class A0, …, class A\ **n**>
*cls*\ (A0 const& a0, …, A\ **n** const& a\ **n**)
: *impl*\ (constructor_parameters ## __LINE__(a0, …, a\ **n**))
{}
:vellipsis:`⋮`
template <class A0, …, class A\ **m**>
*cls*\ (A0 const& a0, …, A\ **n** const& a\ **m**)
: *impl*\ (constructor_parameters ## __LINE__(a0, …, a\ **m**))
{}
``BOOST_PARAMETER_NAME(name)``
------------------------------
Declares a tag-type and keyword object.
Expands to:
**If** *name* is of the form:
.. parsed-literal::
(*tag-name*, *namespace-name*) *object-name*
**then**
.. parsed-literal::
namespace *namespace-name*
{
struct *tag-name*
{
static char const* keyword_name()
{
return ##\ *tag-name*;
}
typedef *unspecified* _;
typedef *unspecified* _1;
};
}
::boost::parameter::keyword<*tag-namespace*\ ::\ *tag-name*\ > const& *object-name*
= ::boost::parameter::keyword<*tag-namespace*\ ::\ *tag-name*\ >::instance;
**Else**
.. parsed-literal::
namespace tag
{
struct *name*
{
static char const* keyword_name()
{
return ##\ *name*;
}
typedef *unspecified* _;
typedef *unspecified* _1;
};
}
::boost::parameter::keyword<tag::\ *name*\ > const& _\ *name*
= ::boost::parameter::keyword<tag::\ *name*\ >::instance;
``BOOST_PARAMETER_TEMPLATE_KEYWORD(name)``
------------------------------------------
Expands to:
.. parsed-literal::
namespace tag
{
struct *name*;
}
template <class T>
struct *name*
: ::boost::parameter::template_keyword<tag::\ *name*, T>
{};
``BOOST_PARAMETER_FUN(r,n,l,h,p)``
----------------------------------
.. admonition:: Deprecated
This macro has been deprecated in favor of
``BOOST_PARAMETER_FUNCTION``.
Generates a sequence of `forwarding function`_ templates named
``n``, with arities ranging from ``l`` to ``h`` , returning ``r``,
and using ``p`` to control overload resolution and assign tags to
@@ -890,9 +583,7 @@ Generates
{
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**
@@ -907,11 +598,6 @@ Generates
``BOOST_PARAMETER_KEYWORD(n,k)``
--------------------------------
.. admonition:: Deprecated
This macro has been deprecated in favor of
``BOOST_PARAMETER_NAME``.
Generates the declaration of a |keyword tag type| named ``k`` in
namespace ``n``, and a corresponding |keyword object| definition in
the enclosing namespace.
@@ -997,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

@@ -1,21 +0,0 @@
// Copyright David Abrahams, 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)
// See www.boost.org/libs/parameter for documentation.
#ifndef BOOST_PARAMETER_050401_HPP
#define BOOST_PARAMETER_050401_HPP
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/value_type.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/parameter/match.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/preprocessor.hpp>
#endif // BOOST_PARAMETER_050401_HPP

116
include/boost/parameter/aux_/arg_list.hpp Normal file → Executable file
View File

@@ -11,7 +11,7 @@
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/maybe.hpp>
#include <boost/parameter/aux_/maybe_fwd.hpp>
#include <boost/parameter/config.hpp>
#include <boost/mpl/apply.hpp>
@@ -22,10 +22,12 @@
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_and_derived.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.
@@ -33,9 +35,6 @@ template<class T> struct keyword;
namespace aux {
// Tag type passed to MPL lambda.
struct lambda_tag;
//
// Structures used to build the tuple of actual arguments. The
// tuple is a nested cons-style list of arg_list specializations
@@ -71,7 +70,7 @@ struct empty_arg_list
// lookup given that default
struct binding
{
template<class KW, class Default, class Reference>
template<class KW, class Default>
struct apply
{
typedef Default type;
@@ -141,9 +140,9 @@ struct empty_arg_list
// was found if we match this overload, so unless that parameter
// has a default, we indicate that the actual arguments don't
// match the function's requirements.
template <class ParameterRequirements, class ArgPack>
template <class ParameterRequirements>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*, ArgPack*);
satisfies(ParameterRequirements*);
// MPL sequence support
typedef empty_arg_list type; // convenience
@@ -159,17 +158,6 @@ no_tag operator*(empty_arg_list, KW*);
template <class KW, class T>
struct tagged_argument;
template <class T>
struct is_maybe
: is_base_and_derived<maybe_base, T>
{};
template <class T>
struct get_reference
{
typedef typename T::reference type;
};
// 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>
@@ -177,20 +165,8 @@ struct arg_list : Next
{
typedef arg_list<TaggedArg,Next> self;
typedef typename TaggedArg::key_type key_type;
typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;
typedef typename mpl::eval_if<
holds_maybe
, get_reference<typename TaggedArg::value_type>
, get_reference<TaggedArg>
>::type reference;
typedef typename mpl::if_<
holds_maybe
, reference
, typename TaggedArg::value_type
>::type value_type;
typedef typename TaggedArg::value_type value_type;
typedef typename TaggedArg::reference reference;
TaggedArg arg; // Stores the argument
@@ -198,12 +174,12 @@ struct arg_list : Next
template< // class A0, class A1, ...
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
>
arg_list( // A0& a0, A1& a1, ...
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & 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_reference()
, void_()
)
, arg(a0)
{}
@@ -216,18 +192,19 @@ struct arg_list : Next
, 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, class Reference>
template <class KW, class Default>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::if_<Reference, reference, value_type>
, mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
>::type type;
};
};
@@ -257,20 +234,6 @@ struct arg_list : Next
// specific arguments by name
//
// Helpers that handle the case when TaggedArg is
// empty<T>.
template <class D>
reference get_default(D const&, mpl::false_) const
{
return arg.value;
}
template <class D>
reference get_default(D const& d, mpl::true_) const
{
return arg.value ? arg.value.get() : arg.value.construct(d.value);
}
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__GNUC__, < 3) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
@@ -297,7 +260,7 @@ struct arg_list : Next
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
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;
@@ -305,7 +268,7 @@ struct arg_list : Next
}
template <class KW, class Default>
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
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;
@@ -313,10 +276,9 @@ struct arg_list : Next
}
template <class KW, class F>
typename mpl::apply_wrap3<
typename mpl::apply_wrap2<
binding,KW
, typename result_of0<F>::type
, mpl::true_
>::type
operator[](lazy_default<KW,F> x) const
{
@@ -330,14 +292,13 @@ struct arg_list : Next
// passed, compilation fails.
reference get(keyword<key_type> const&) const
{
BOOST_MPL_ASSERT_NOT((holds_maybe));
return arg.value;
}
template <class Default>
reference get(default_<key_type,Default> const& d) const
reference get(default_<key_type,Default>) const
{
return get_default(d, holds_maybe());
return arg.value;
}
template <class Default>
@@ -348,16 +309,33 @@ struct arg_list : Next
#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
{
BOOST_MPL_ASSERT_NOT((holds_maybe));
return arg.value;
}
template <class Default>
reference operator[](default_<key_type, Default> const& d) const
template <class T, class D>
default_reference get_value(T&, D&) const
{
return get_default(d, holds_maybe());
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>
@@ -382,14 +360,10 @@ struct arg_list : Next
// compile-time computation and never really called, so a
// declaration is enough.
//
template <class HasDefault, class Predicate, class ArgPack>
static typename mpl::apply_wrap2<
typename mpl::lambda<Predicate, lambda_tag>::type
, value_type, ArgPack
>::type
template <class HasDefault, class Predicate>
static typename mpl::apply1<Predicate, value_type>::type
satisfies(
parameter_requirements<key_type,Predicate,HasDefault>*
, ArgPack*
);
// Builds an overload set including satisfies functions defined
@@ -401,7 +375,7 @@ struct arg_list : Next
// 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) const
operator,(tagged_argument<KW,T2> x)
{
return arg_list<tagged_argument<KW,T2>, self>(x, *this);
}

View File

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

14
include/boost/parameter/aux_/default.hpp Normal file → Executable file
View File

@@ -4,9 +4,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEFAULT_050329_HPP
# define DEFAULT_050329_HPP
# include <boost/detail/workaround.hpp>
#define DEFAULT_050329_HPP
namespace boost { namespace parameter { namespace aux {
@@ -29,7 +27,7 @@ struct default_
// the user when resolving the value of the parameter with the
// given keyword
//
# if BOOST_WORKAROUND(__EDG_VERSION__, <= 300)
#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.
@@ -50,8 +48,8 @@ struct lazy_default
: lazy_default_base<KW,DefaultComputer>(x)
{}
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
# else
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
#else
template <class KW, class DefaultComputer>
struct lazy_default
{
@@ -60,8 +58,8 @@ struct lazy_default
{}
DefaultComputer const& compute_default;
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
# endif
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
#endif
}}} // namespace boost::parameter::aux

78
include/boost/parameter/aux_/maybe.hpp Normal file → Executable file
View File

@@ -1,79 +1,38 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// 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_060211_HPP
# define BOOST_PARAMETER_MAYBE_060211_HPP
#ifndef BOOST_PARAMETER_MAYBE_051212_HPP
# define BOOST_PARAMETER_MAYBE_051212_HPP
# include <boost/mpl/if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/optional.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/optional.hpp>
# include <boost/mpl/if.hpp>
namespace boost { namespace parameter { namespace aux {
struct maybe_base {};
struct empty_maybe_tag {};
template <class T>
struct maybe : maybe_base
struct maybe
{
typedef typename add_reference<
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
T const
# else
typename add_const<T>::type
# endif
typedef typename mpl::if_<
is_reference<T>
, T
, typename add_reference<typename add_const<T>::type>::type
>::type reference;
typedef typename remove_cv<
BOOST_DEDUCED_TYPENAME remove_reference<reference>::type
>::type non_cv_value;
explicit maybe(T value)
: value(value)
, constructed(false)
{}
maybe()
: constructed(false)
{}
~maybe()
{
if (constructed)
this->destroy();
}
reference construct(reference value) const
{
return value;
}
template <class U>
reference construct2(U const& value) const
{
new (m_storage.bytes) non_cv_value(value);
constructed = true;
return *(non_cv_value*)m_storage.bytes;
}
template <class U>
reference construct(U const& value) const
{
return this->construct2(value);
}
void destroy()
{
((non_cv_value*)m_storage.bytes)->~non_cv_value();
}
explicit maybe(reference x)
: value(x)
{}
typedef reference(maybe<T>::*safe_bool)() const;
operator safe_bool() const
{
return value ? &maybe<T>::get : 0 ;
@@ -84,15 +43,10 @@ struct maybe : maybe_base
return value.get();
}
private:
boost::optional<T> value;
mutable bool constructed;
mutable typename boost::python::detail::referent_storage<
reference
>::type m_storage;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_MAYBE_060211_HPP
#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

35
include/boost/parameter/aux_/overloads.hpp Normal file → Executable file
View File

@@ -44,40 +44,29 @@
#define N BOOST_PP_ITERATION()
#define BOOST_PARAMETER_open_list(z, n, text) \
aux::item< \
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) \
aux::make_arg_list< \
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
, void_ \
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \
, deduced_list \
, aux::tag_keyword_arg \
>
#define BOOST_PARAMETER_arg_pack_init(z, n, limit) \
BOOST_PP_CAT(a, BOOST_PP_SUB(limit,n))
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 mpl::first<
typename BOOST_PARAMETER_arg_list(N)::type
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, & a)) const
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 result;
typedef typename BOOST_PARAMETER_arg_list(N)::type arg_tuple;
typedef typename mpl::first<result>::type result_type;
typedef typename mpl::second<result>::type error;
error();
return result_type(
BOOST_PP_ENUM(N, BOOST_PARAMETER_arg_pack_init, BOOST_PP_DEC(N))
return arg_tuple(
BOOST_PP_ENUM_PARAMS(N, a)
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N)
, aux::void_reference() BOOST_PP_INTERCEPT
, aux::void_() BOOST_PP_INTERCEPT
));
}

View File

View File

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

View File

@@ -1,115 +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)
#ifndef BOOST_PARAMETER_FLATTEN_051217_HPP
# define BOOST_PARAMETER_FLATTEN_051217_HPP
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/tuple/rem.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/seq/for_each.hpp>
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/identity.hpp>
# include <boost/preprocessor/selection/max.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/repetition/enum_trailing.hpp>
# include <boost/parameter/aux_/preprocessor/for_each.hpp>
# define BOOST_PARAMETER_FLATTEN_SPLIT_required required,
# define BOOST_PARAMETER_FLATTEN_SPLIT_optional optional,
# define BOOST_PARAMETER_FLATTEN_SPLIT_deduced deduced,
# define BOOST_PARAMETER_FLATTEN_SPLIT(sub) \
BOOST_PP_CAT(BOOST_PARAMETER_FLATTEN_SPLIT_, sub)
# define BOOST_PARAMETER_FLATTEN_QUALIFIER(sub) \
BOOST_PP_SPLIT(0, BOOST_PARAMETER_FLATTEN_SPLIT(sub))
# define BOOST_PARAMETER_FLATTEN_ARGS(sub) \
BOOST_PP_SPLIT(1, BOOST_PARAMETER_FLATTEN_SPLIT(sub))
# define BOOST_PARAMETER_FLATTEN_ARITY_optional(arities) \
BOOST_PP_TUPLE_ELEM(3,0,arities)
# define BOOST_PARAMETER_FLATTEN_ARITY_required(arities) \
BOOST_PP_TUPLE_ELEM(3,1,arities)
# define BOOST_PARAMETER_FLATTEN_SPEC0_DUMMY_ELEM(z, n, data) ~
# define BOOST_PARAMETER_FLATTEN_SPEC0(r, n, elem, data) \
(( \
BOOST_PP_TUPLE_ELEM(3,2,data) \
, BOOST_PP_TUPLE_REM(BOOST_PP_TUPLE_ELEM(3,0,data)) elem \
BOOST_PP_ENUM_TRAILING( \
BOOST_PP_SUB( \
BOOST_PP_TUPLE_ELEM(3,1,data) \
, BOOST_PP_TUPLE_ELEM(3,0,data) \
) \
, BOOST_PARAMETER_FLATTEN_SPEC0_DUMMY_ELEM \
, ~ \
) \
))
# define BOOST_PARAMETER_FLATTEN_SPEC_AUX(r, arity, max_arity, spec, transform) \
BOOST_PARAMETER_FOR_EACH_R( \
r \
, arity \
, BOOST_PARAMETER_FLATTEN_ARGS(spec) \
, (arity, max_arity, transform(BOOST_PARAMETER_FLATTEN_QUALIFIER(spec))) \
, BOOST_PARAMETER_FLATTEN_SPEC0 \
)
# define BOOST_PARAMETER_FLATTEN_IDENTITY(x) x
# define BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_AUX( \
r \
, BOOST_PP_CAT( \
BOOST_PARAMETER_FLATTEN_ARITY_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \
)(arities) \
, BOOST_PP_TUPLE_ELEM(3,2,arities) \
, spec \
, BOOST_PARAMETER_FLATTEN_IDENTITY \
)
# define BOOST_PARAMETER_FLATTEN_SPEC_required(r, arities, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec)
# define BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED(x) BOOST_PP_CAT(deduced_,x)
# define BOOST_PARAMETER_FLATTEN_SPEC_deduced_M(r, arities, n, spec) \
BOOST_PARAMETER_FLATTEN_SPEC_AUX( \
r \
, BOOST_PP_CAT( \
BOOST_PARAMETER_FLATTEN_ARITY_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \
)(arities) \
, BOOST_PP_TUPLE_ELEM(3,2,arities) \
, spec \
, BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED \
)
# define BOOST_PARAMETER_FLATTEN_SPEC_deduced(r, arities, spec) \
BOOST_PP_SEQ_FOR_EACH_I_R( \
r \
, BOOST_PARAMETER_FLATTEN_SPEC_deduced_M \
, arities \
, BOOST_PARAMETER_FLATTEN_ARGS(spec) \
)
# define BOOST_PARAMETER_FLATTEN_SPEC(r, arities, spec) \
BOOST_PP_CAT( \
BOOST_PARAMETER_FLATTEN_SPEC_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \
)(r, arities, spec)
# define BOOST_PARAMETER_FLATTEN(optional_arity, required_arity, wanted_arity, specs) \
BOOST_PP_SEQ_FOR_EACH( \
BOOST_PARAMETER_FLATTEN_SPEC \
, ( \
optional_arity, required_arity \
, wanted_arity \
) \
, specs \
)
#endif // BOOST_PARAMETER_FLATTEN_051217_HPP

View File

@@ -1,103 +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)
#ifndef BOOST_PARAMETER_FOR_EACH_051217_HPP
# define BOOST_PARAMETER_FOR_EACH_051217_HPP
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/detail/split.hpp>
# include <boost/preprocessor/logical/not.hpp>
# include <boost/preprocessor/facilities/is_empty.hpp>
# include <boost/preprocessor/tuple/eat.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/punctuation/comma_if.hpp>
# include <boost/preprocessor/for.hpp>
# include <boost/preprocessor/repetition/deduce_r.hpp>
# define BOOST_PARAMETER_FOR_EACH_head_aux2(x,y) (x,y), ~
# define BOOST_PARAMETER_FOR_EACH_head_aux3(x,y,z) (x,y,z), ~
# define BOOST_PARAMETER_FOR_EACH_head_aux4(x,y,z,u) (x,y,z,u), ~
# define BOOST_PARAMETER_FOR_EACH_head(n,x) \
BOOST_PP_SPLIT(0, BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_head_aux,n) x)
# define BOOST_PARAMETER_FOR_EACH_pred_aux_BOOST_PARAMETER_FOR_EACH_END_SENTINEL
# define BOOST_PARAMETER_FOR_EACH_pred_aux_check(x) \
BOOST_PP_NOT(BOOST_PP_IS_EMPTY( \
BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_pred_aux_, x) \
)), ~
# define BOOST_PARAMETER_FOR_EACH_pred_aux2(x,y) \
BOOST_PARAMETER_FOR_EACH_pred_aux_check(x)
# define BOOST_PARAMETER_FOR_EACH_pred_aux3(x,y,z) \
BOOST_PARAMETER_FOR_EACH_pred_aux_check(x)
# define BOOST_PARAMETER_FOR_EACH_pred_aux4(x,y,z,u) \
BOOST_PARAMETER_FOR_EACH_pred_aux_check(x)
# define BOOST_PARAMETER_FOR_EACH_pred_aux0(n,x) \
BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_pred_aux,n) x
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
# define BOOST_PARAMETER_FOR_EACH_pred_SPLIT_FIRST(x) \
BOOST_PP_SPLIT(0, x)
# define BOOST_PARAMETER_FOR_EACH_pred(r, state) \
BOOST_PARAMETER_FOR_EACH_pred_SPLIT_FIRST( \
BOOST_PARAMETER_FOR_EACH_pred_aux0( \
BOOST_PP_TUPLE_ELEM(5,3,state) \
, BOOST_PP_TUPLE_ELEM(5,0,state) \
) \
)
# else
# define BOOST_PARAMETER_FOR_EACH_pred(r, state) \
BOOST_PP_SPLIT( \
0 \
, BOOST_PARAMETER_FOR_EACH_pred_aux0( \
BOOST_PP_TUPLE_ELEM(5,3,state) \
, BOOST_PP_TUPLE_ELEM(5,0,state) \
) \
)
# endif
# define BOOST_PARAMETER_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 BOOST_PARAMETER_FOR_EACH_macro(r, state) \
BOOST_PP_TUPLE_ELEM(5,2,state)( \
r \
, BOOST_PP_TUPLE_ELEM(5,4,state) \
, BOOST_PARAMETER_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 BOOST_PARAMETER_FOR_EACH_build_end_sentinel(z,n,text) \
BOOST_PP_COMMA_IF(n) BOOST_PARAMETER_FOR_EACH_END_SENTINEL
# define BOOST_PARAMETER_FOR_EACH_build_end_sentinel_tuple(arity) \
( \
BOOST_PP_REPEAT(arity, BOOST_PARAMETER_FOR_EACH_build_end_sentinel, _) \
)
# define BOOST_PARAMETER_FOR_EACH_R(r, arity, list, data, macro) \
BOOST_PP_CAT(BOOST_PP_FOR_, r)( \
(list BOOST_PARAMETER_FOR_EACH_build_end_sentinel_tuple(arity), data, macro, arity, 0) \
, BOOST_PARAMETER_FOR_EACH_pred \
, BOOST_PARAMETER_FOR_EACH_op \
, BOOST_PARAMETER_FOR_EACH_macro \
)
# define BOOST_PARAMETER_FOR_EACH(arity, list, data, macro) \
BOOST_PARAMETER_FOR_EACH_R(BOOST_PP_DEDUCE_R(), arity, list, data, macro)
#endif // BOOST_PARAMETER_FOR_EACH_051217_HPP

0
include/boost/parameter/aux_/result_of0.hpp Normal file → Executable file
View File

View File

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

0
include/boost/parameter/aux_/tag.hpp Normal file → Executable file
View File

152
include/boost/parameter/aux_/tagged_argument.hpp Normal file → Executable file
View File

@@ -3,32 +3,20 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
# define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
#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/parameter/aux_/result_of0.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/apply_wrap.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/not.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_reference.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 {
struct empty_arg_list;
struct arg_list_tag;
struct tagged_argument_base {};
// Holds a reference to an argument of type Arg associated with
// keyword Keyword
template <class Keyword, class Arg>
struct tagged_argument : tagged_argument_base
struct tagged_argument
{
typedef Keyword key_type;
typedef Arg value_type;
@@ -36,22 +24,6 @@ struct tagged_argument : tagged_argument_base
tagged_argument(reference x) : value(x) {}
// 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, class Reference>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::if_<Reference, reference, value_type>
, mpl::identity<Default>
>::type type;
};
};
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class Keyword2, class Arg2>
@@ -69,120 +41,20 @@ struct tagged_argument : tagged_argument_base
, arg_list<tagged_argument<Keyword2, Arg2> >(x, empty_arg_list())
);
}
reference operator[](keyword<Keyword> const&) const
{
return value;
}
# if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class KW, class Default>
Default& get_with_default(default_<KW,Default> const& x, int) const
{
return x.value;
}
template <class Default>
reference get_with_default(default_<key_type,Default> const&, long) const
{
return value;
}
template <class KW, class Default>
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
operator[](default_<KW,Default> const& x) const
{
return get_with_default(x, 0L);
}
template <class KW, class F>
typename result_of0<F>::type
get_with_lazy_default(lazy_default<KW,F> const& x, int) const
{
return x.compute_default();
}
template <class F>
reference get_with_lazy_default(lazy_default<key_type,F> const&, long) const
{
return value;
}
template <class KW, class F>
typename mpl::apply_wrap3<
binding,KW
, typename result_of0<F>::type
, mpl::true_
>::type
operator[](lazy_default<KW,F> const& x) const
{
return get_with_lazy_default(x, 0L);
}
# else
template <class Default>
reference operator[](default_<key_type,Default> const& x) const
{
return value;
}
template <class F>
reference operator[](lazy_default<key_type,F> const& x) const
{
return value;
}
template <class KW, class Default>
Default& operator[](default_<KW,Default> const& x) const
{
return x.value;
}
template <class KW, class F>
typename result_of0<F>::type operator[](lazy_default<KW,F> const& x) const
{
return x.compute_default();
}
template <class ParameterRequirements>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
template <class HasDefault, class Predicate>
static typename mpl::apply1<Predicate, value_type>::type
satisfies(
parameter_requirements<key_type,Predicate,HasDefault>*
);
# endif
reference value;
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
// warning suppression
private:
void operator=(tagged_argument const&);
public:
# endif
// MPL sequence support
typedef tagged_argument type; // Convenience for users
typedef empty_arg_list tail_type; // For the benefit of iterators
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
#endif
};
// Defines a metafunction, is_tagged_argument, that identifies
// tagged_argument specializations and their derived classes.
template <class T>
struct is_tagged_argument_aux
: is_convertible<T*,tagged_argument_base const*>
{};
template <class T>
struct is_tagged_argument
: mpl::and_<
mpl::not_<is_reference<T> >
, is_tagged_argument_aux<T>
>
{};
// tagged_argument specializations.
BOOST_DETAIL_IS_XXX_DEF(tagged_argument,tagged_argument,2)
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
#endif // TAGGED_ARGUMENT_050328_HPP

View File

@@ -1,47 +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)
#ifndef BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP
# define BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP
# include <boost/mpl/and.hpp>
# include <boost/mpl/not.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_reference.hpp>
namespace boost { namespace parameter {
namespace aux
{
struct template_keyword_tag {};
template <class T, class U>
struct is_pointer_convertible
: is_convertible<T*, U*>
{};
template <class T>
struct is_template_keyword
: mpl::and_<
mpl::not_<is_reference<T> >
, is_pointer_convertible<T, template_keyword_tag>
>
{};
} // namespace aux
template <class Tag, class T>
struct template_keyword
: aux::template_keyword_tag
{
typedef Tag key_type;
typedef T value_type;
typedef value_type reference;
};
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP

0
include/boost/parameter/aux_/unwrap_cv_reference.hpp Normal file → Executable file
View File

21
include/boost/parameter/aux_/void.hpp Normal file → Executable file
View File

@@ -3,27 +3,16 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_VOID_050329_HPP
#define BOOST_PARAMETER_VOID_050329_HPP
#ifndef VOID_050329_HPP
#define VOID_050329_HPP
namespace boost { namespace parameter {
namespace boost { namespace parameter { namespace aux {
// A placemarker for "no argument passed."
// MAINTAINER NOTE: Do not make this into a metafunction
struct void_ {};
namespace aux
{
}}} // namespace boost::parameter::aux
inline void_& void_reference()
{
static void_ instance;
return instance;
}
} // namespace aux
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_VOID_050329_HPP
#endif // VOID_050329_HPP

0
include/boost/parameter/aux_/yesno.hpp Normal file → Executable file
View File

79
include/boost/parameter/binding.hpp Normal file → Executable file
View File

@@ -5,83 +5,35 @@
# define BOOST_PARAMETER_BINDING_DWA200558_HPP
# include <boost/mpl/apply.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/and.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/parameter/aux_/void.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/mpl/eval_if.hpp>
# endif
# 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) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct binding0
{
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::true_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
};
# endif
template <class Parameters, class Keyword, class Default = void_>
# 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
struct binding_eti
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
, binding0<Parameters,Keyword,Default>
>::type type;
# else
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::true_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
# endif
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class Parameters, class Keyword, class Default = void_>
template <class Parameters, class Keyword, class Default = aux::void_>
struct binding
{
typedef typename mpl::eval_if<
is_same<Parameters, int>
, mpl::identity<int>
, binding_eti<Parameters, Keyword, Default>
typedef typename mpl::apply_wrap2<
typename Parameters::binding,Keyword,
typename mpl::if_<is_same<Default,aux::void_>,void,Default>::type
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
};
# endif
@@ -92,11 +44,10 @@ struct binding
template <class Parameters, class Keyword, class DefaultFn>
struct lazy_binding
{
typedef typename mpl::apply_wrap3<
typedef typename mpl::apply_wrap2<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
, mpl::true_
>::type type;
};

0
include/boost/parameter/config.hpp Normal file → Executable file
View File

52
include/boost/parameter/keyword.hpp Normal file → Executable file
View File

@@ -9,6 +9,7 @@
#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 {
@@ -28,10 +29,10 @@ namespace boost { namespace parameter {
// f(rate = 1, skew = 2.4);
//
template <class Tag>
struct keyword
struct keyword : noncopyable
{
template <class T>
typename aux::tag<Tag, T>::type const
typename aux::tag<Tag, T>::type
operator=(T& x) const
{
typedef typename aux::tag<Tag, T>::type result;
@@ -54,7 +55,7 @@ struct keyword
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
template <class T>
typename aux::tag<Tag, T const>::type const
typename aux::tag<Tag, T const>::type
operator=(T const& x) const
{
typedef typename aux::tag<Tag, T const>::type result;
@@ -91,18 +92,17 @@ struct keyword
// 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> const instance;
// This interface is deprecated
static keyword<Tag>& get()
{
return const_cast<keyword<Tag>&>(instance);
static keyword<Tag> result;
return result;
}
private:
keyword() {}
};
template <class Tag>
keyword<Tag> const keyword<Tag>::instance = {};
// 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
@@ -111,37 +111,19 @@ keyword<Tag> const keyword<Tag>::instance = {};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace \
{ \
struct name \
{ \
static char const* keyword_name() \
{ \
return #name; \
} \
}; \
} \
static ::boost::parameter::keyword<tag_namespace::name> const& name \
= ::boost::parameter::keyword<tag_namespace::name>::instance;
# 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 \
{ \
static char const* keyword_name() \
{ \
return #name; \
} \
}; \
} \
namespace tag_namespace { struct name; } \
namespace \
{ \
::boost::parameter::keyword<tag_namespace::name> const& name \
= ::boost::parameter::keyword<tag_namespace::name>::instance;\
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get(); \
}
#endif

3
include/boost/parameter/macros.hpp Normal file → Executable file
View File

@@ -15,14 +15,13 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/detail/workaround.hpp>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \
template<BOOST_PP_ENUM_PARAMS(n, class T)>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n)
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
#ifndef BOOST_NO_SFINAE
# define BOOST_PARAMETER_MATCH_TYPE(n, param) \
BOOST_PP_EXPR_IF(n, typename) param::match \

2
include/boost/parameter/match.hpp Normal file → Executable file
View File

@@ -29,7 +29,7 @@
BOOST_PARAMETER_MAX_ARITY \
, BOOST_PP_SEQ_SIZE(ArgTypes) \
) \
, ::boost::parameter::void_ BOOST_PP_INTERCEPT \
, ::boost::parameter::aux::void_ BOOST_PP_INTERCEPT \
)
# else

View File

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

819
include/boost/parameter/parameters.hpp Normal file → Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,6 @@
# include <boost/mpl/begin.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/mpl/size.hpp>
# include <boost/parameter/keyword.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
@@ -29,21 +28,6 @@ struct make_invoker
};
};
template <long Arity, class M, class R, class T, class Args>
struct member_invoker;
template <class M, class R, class T>
struct make_member_invoker
{
template <class Args>
struct apply
{
typedef member_invoker<
mpl::size<Args>::value, M, R, T, Args
> type;
};
};
template <long Arity, class T, class R, class Args>
struct call_invoker;
@@ -83,15 +67,6 @@ struct invoker<0, M, R, Args>
}
};
template <class M, class R, class T, class Args>
struct member_invoker<0, M, R, T, Args>
{
static R execute(T& self)
{
return M()(boost::type<R>(), self);
}
};
template <class T, class R, class Args>
struct call_invoker<0, T, R, Args>
{
@@ -111,19 +86,15 @@ struct init_invoker<0, T, Args>
};
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/aux_/python/invoker_iterate.hpp>, 1))
(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/aux_/python/invoker_iterate.hpp>, 2))
(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/aux_/python/invoker_iterate.hpp>, 3))
# include BOOST_PP_ITERATE()
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/aux_/python/invoker_iterate.hpp>, 4))
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 3))
# include BOOST_PP_ITERATE()
}}}} // namespace boost::parameter::python::aux

View File

@@ -34,9 +34,6 @@ struct call_invoker<N, T, R, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 3
template <class T, class Args>
struct init_invoker<N, T, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 4
template <class M, class R, class T, class Args>
struct member_invoker<N, M, R, T, Args>
#endif
{
typedef typename mpl::begin<Args>::type iter0;
@@ -54,13 +51,13 @@ struct member_invoker<N, M, R, T, Args>
BOOST_PP_REPEAT_FROM_TO(1, N, BOOST_PARAMETER_PY_ARG_TYPES, ~)
static
#if BOOST_PP_ITERATION_FLAGS() == 3
T*
#else
#if BOOST_PP_ITERATION_FLAGS() == 1 || BOOST_PP_ITERATION_FLAGS() == 2
R
#else
T*
#endif
execute(
#if BOOST_PP_ITERATION_FLAGS() == 2 || BOOST_PP_ITERATION_FLAGS() == 4
#if BOOST_PP_ITERATION_FLAGS() == 2
T& self
,
#endif
@@ -68,21 +65,18 @@ struct member_invoker<N, M, R, T, Args>
)
{
return
#if BOOST_PP_ITERATION_FLAGS() == 1 || BOOST_PP_ITERATION_FLAGS() == 4
#if BOOST_PP_ITERATION_FLAGS() == 1
M()(
boost::type<R>()
# if BOOST_PP_ITERATION_FLAGS() == 4
, self
# endif
, BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
, BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 2
self(
BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 3
new T(
BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#endif
}

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

@@ -1,9 +1,9 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// 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_PYTHON_060209_HPP
# define BOOST_PARAMETER_PYTHON_060209_HPP
#ifndef BOOST_PARAMETER_GENERAL_051210_HPP
# define BOOST_PARAMETER_GENERAL_051210_HPP
# include <boost/mpl/vector.hpp>
# include <boost/mpl/fold.hpp>
@@ -22,69 +22,68 @@
# include <boost/mpl/next.hpp>
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/empty.hpp>
# include <boost/type.hpp>
# include <boost/python/def.hpp>
# include <boost/python/make_constructor.hpp>
# include <boost/python/init.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/parameter/python/aux_/invoker.hpp>
# include <boost/parameter/aux_/maybe.hpp>
# include <boost/parameter/aux_/python/invoker.hpp>
namespace boost { namespace parameter { namespace python
namespace boost { namespace parameter { namespace python {
PyObject* init_sentinel()
{
namespace python_ = boost::python;
}}}
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 */
};
namespace boost { namespace parameter { namespace python { namespace aux
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;
}
inline PyObject* unspecified_type()
{
static PyTypeObject unspecified = {
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 */
};
struct empty_tag_to_python
{
empty_tag_to_python()
{
boost::python::to_python_converter<
boost::parameter::aux::empty_maybe_tag, empty_tag_to_python
>();
if (unspecified.ob_type == 0)
{
unspecified.ob_type = &PyType_Type;
PyType_Ready(&unspecified);
}
sentinel_value() = boost::python::handle<>(init_sentinel());
}
return (PyObject*)&unspecified;
}
static PyObject* convert(boost::parameter::aux::empty_maybe_tag)
{
return boost::python::xincref(sentinel_value().get());
}
};
struct empty_tag {};
struct empty_tag_to_python
{
static PyObject* convert(empty_tag)
{
return python_::xincref(unspecified_type());
}
};
}}}} // namespace boost::parameter::python::aux
}}} // namespace boost::parameter::python
namespace boost { namespace python
{
@@ -96,23 +95,30 @@ namespace boost { namespace python
{
arg_from_python(PyObject* p)
: arg_from_python<T>(p)
, empty(parameter::python::aux::unspecified_type() == p)
{}
, empty(false)
{
if (parameter::python::sentinel_value().get() == p)
{
empty = true;
}
}
bool convertible() const
{
return empty || arg_from_python<T>::convertible();
if (empty) return true;
return arg_from_python<T>::convertible();
}
parameter::aux::maybe<T> operator()()
boost::parameter::aux::maybe<T> operator()()
{
if (empty)
{
return parameter::aux::maybe<T>();
return boost::parameter::aux::maybe<T>();
}
else
{
return parameter::aux::maybe<T>(
return boost::parameter::aux::maybe<T>(
arg_from_python<T>::operator()()
);
}
@@ -207,6 +213,12 @@ namespace aux
}
};
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_)
@@ -217,7 +229,7 @@ namespace aux
def_combination_aux(
def, f, typename mpl::next<Iter>::type(), End()
, (
keywords, boost::python::arg(kw::keyword_name())
keywords, boost::python::arg(keyword_name((kw*)0))
)
);
}
@@ -232,14 +244,15 @@ namespace aux
def_combination_aux(
def, f, typename mpl::next<Iter>::type(), End()
, (
keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
keywords, boost::python::arg(kw::keyword())
= boost::parameter::aux::empty_maybe_tag()
)
);
}
inline void initialize_converter()
{
static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
static empty_tag_to_python cv;
}
template <class Def, class F, class Iter, class End, class Keywords>
@@ -248,6 +261,8 @@ namespace aux
{
typedef typename mpl::deref<Iter>::type spec;
initialize_converter();
typedef typename mpl::and_<
typename spec::optimized_default
, mpl::not_<typename spec::required>
@@ -305,8 +320,6 @@ namespace aux
void def_combinations(
Def def, Specs*, Bits, End, Invoker*)
{
initialize_converter();
def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
def_combinations(
@@ -325,84 +338,35 @@ namespace aux
Def, Specs*, End, End, Invoker*)
{}
struct not_specified {};
template <class CallPolicies>
struct call_policies_as_options
{
call_policies_as_options(CallPolicies const& call_policies)
: call_policies(call_policies)
{}
CallPolicies const& policies() const
{
return call_policies;
}
char const* doc() const
{
return 0;
}
CallPolicies call_policies;
};
template <class Class, class Options = not_specified>
template <class Class>
struct def_class
{
def_class(Class& cl, char const* name, Options options = Options())
def_class(Class& cl, char const* name)
: cl(cl)
, name(name)
, options(options)
{}
template <class F>
void def(F f, not_specified const*) const
void operator()(F f) const
{
cl.def(name, f);
}
template <class F>
void def(F f, void const*) const
{
cl.def(name, f, options.doc(), options.policies());
}
template <class F>
void operator()(F f) const
{
this->def(f, &options);
}
template <class F, class Keywords>
void def(F f, Keywords const& keywords, not_specified const*) const
void operator()(F f, Keywords const& keywords) const
{
cl.def(name, f, keywords);
}
template <class F, class Keywords>
void def(F f, Keywords const& keywords, void const*) const
{
cl.def(name, f, keywords, options.doc(), options.policies());
}
template <class F, class Keywords>
void operator()(F f, Keywords const& keywords) const
{
this->def(f, keywords, &options);
}
Class& cl;
char const* name;
Options options;
};
template <class Class, class CallPolicies = boost::python::default_call_policies>
template <class Class>
struct def_init
{
def_init(Class& cl, CallPolicies call_policies = CallPolicies())
def_init(Class& cl)
: cl(cl)
, call_policies(call_policies)
{}
template <class F>
@@ -410,7 +374,7 @@ namespace aux
{
cl.def(
"__init__"
, boost::python::make_constructor(f, call_policies)
, boost::python::make_constructor(f)
);
}
@@ -419,12 +383,13 @@ namespace aux
{
cl.def(
"__init__"
, boost::python::make_constructor(f, call_policies, keywords)
, boost::python::make_constructor(
f, boost::python::default_call_policies(), keywords
)
);
}
Class& cl;
CallPolicies call_policies;
};
struct def_function
@@ -446,8 +411,8 @@ namespace aux
}
char const* name;
};
};
} // namespace aux
template <class M, class Signature>
@@ -464,7 +429,6 @@ void def(char const* name, Signature)
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
@@ -498,7 +462,6 @@ void def(Class& cl, char const* name, Signature)
typename M::keywords
, arg_types
, aux::make_arg_spec<mpl::_1, mpl::_2>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
@@ -529,15 +492,8 @@ namespace aux
template <class K>
struct keyword<K*>
{
typedef K type;
};
template <class K>
struct keyword<K**>
{
typedef K type;
};
: keyword<K>
{};
template <class K>
struct required
@@ -562,174 +518,89 @@ namespace aux
{
typedef mpl::false_ type;
};
template <class T>
struct make_kw_spec;
template <class K, class T>
struct make_kw_spec<K(T)>
struct make_kw_spec
{
typedef arg_spec<
typename keyword<K>::type
, typename required<K>::type
, typename optimized<K>::type
, T
> type;
> type;
};
} // namespace aux
template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
template <class Keywords, class Signature>
struct init
: boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
: boost::python::def_visitor<init<Keywords, Signature> >
{
init(CallPolicies call_policies = CallPolicies())
: call_policies(call_policies)
{}
template <class CallPolicies1>
init<ParameterSpecs, CallPolicies1>
operator[](CallPolicies1 const& call_policies) const
{
return init<ParameterSpecs, CallPolicies1>(call_policies);
}
template <class Class>
void visit_aux(Class& cl, mpl::true_) const
{
cl.def(boost::python::init<>()[call_policies]);
}
template <class Class>
void visit_aux(Class& cl, mpl::false_) const
void visit(Class& cl) const
{
typedef typename mpl::transform<
ParameterSpecs
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
Keywords
, Signature
, aux::make_kw_spec<mpl::_1, mpl::_2>
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_>
, 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, CallPolicies>(cl, call_policies)
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 Class>
void visit(Class& cl) const
{
visit_aux(cl, mpl::empty<ParameterSpecs>());
}
CallPolicies call_policies;
};
template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
template <class Keywords, class Signature>
struct call
: boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
: boost::python::def_visitor<call<Keywords, Signature> >
{
call(CallPolicies const& call_policies = CallPolicies())
: call_policies(call_policies)
{}
template <class CallPolicies1>
call<ParameterSpecs, CallPolicies1>
operator[](CallPolicies1 const& call_policies) const
{
return call<ParameterSpecs, CallPolicies1>(call_policies);
}
template <class Class>
void visit(Class& cl) const
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<ParameterSpecs>::type
typename mpl::begin<Signature>::type
>::type
, typename mpl::end<ParameterSpecs>::type
, typename mpl::end<Signature>::type
> arg_types;
typedef typename mpl::front<ParameterSpecs>::type result_type;
typedef typename mpl::transform<
arg_types
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
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::_>
, 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;
typedef aux::call_policies_as_options<CallPolicies> options;
aux::def_combinations(
aux::def_class<Class, options>(cl, "__call__", options(call_policies))
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
);
}
CallPolicies call_policies;
};
template <class Fwd, class ParameterSpecs>
struct function
: boost::python::def_visitor<function<Fwd, ParameterSpecs> >
{
template <class Class, class Options>
void visit(Class& cl, char const* name, Options const& options) const
{
typedef mpl::iterator_range<
typename mpl::next<
typename mpl::begin<ParameterSpecs>::type
>::type
, typename mpl::end<ParameterSpecs>::type
> arg_types;
typedef typename mpl::front<ParameterSpecs>::type result_type;
typedef typename mpl::transform<
arg_types
, aux::make_kw_spec<mpl::_>
, mpl::back_inserter<mpl::vector0<> >
>::type arg_specs;
typedef typename mpl::count_if<
arg_specs
, aux::is_optional<mpl::_>
>::type optional_arity;
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
aux::def_combinations(
aux::def_class<Class, Options>(cl, name, options)
, (arg_specs*)0
, mpl::long_<0>()
, mpl::long_<upper::value>()
, (aux::make_member_invoker<
Fwd, result_type, typename Class::wrapped_type
>*)0
);
}
};
}}} // namespace boost::parameter::python
#endif // BOOST_PARAMETER_PYTHON_060209_HPP
#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,108 +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)
#ifndef BOOST_PARAMETER_VALUE_TYPE_060921_HPP
# define BOOST_PARAMETER_VALUE_TYPE_060921_HPP
# include <boost/mpl/apply.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/and.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/mpl/eval_if.hpp>
# endif
namespace boost { namespace parameter {
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns Default
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct value_type0
{
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::false_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
};
# endif
template <class Parameters, class Keyword, class Default = void_>
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct value_type
# else
struct value_type_eti
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
, value_type0<Parameters,Keyword,Default>
>::type type;
# else
typedef typename mpl::apply_wrap3<
typename Parameters::binding,Keyword,Default,mpl::false_
>::type type;
BOOST_MPL_ASSERT_NOT((
mpl::and_<
is_same<Default, void_>
, is_same<type, void_>
>
));
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
# endif
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class Parameters, class Keyword, class Default = void_>
struct value_type
{
typedef typename mpl::eval_if<
is_same<Parameters, int>
, mpl::identity<int>
, value_type_eti<Parameters, Keyword, Default>
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
};
# endif
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns the type returned by invoking
// DefaultFn
template <class Parameters, class Keyword, class DefaultFn>
struct lazy_value_type
{
typedef typename mpl::apply_wrap3<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
, mpl::false_
>::type type;
};
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_VALUE_TYPE_060921_HPP

5
index.html Normal file → Executable file
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 +0,0 @@
boost_module(parameter DEPENDS python)

View File

@@ -1,31 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
boost_additional_test_dependencies(optional BOOST_DEPENDS test timer)
boost_test_run(basics)
boost_test_run(sfinae)
boost_test_run(macros)
boost_test_run(earwicker)
boost_test_run(tutorial)
boost_test_run(singular)
boost_test_run(mpl)
boost_test_run(preprocessor)
boost_test_run(preprocessor_deduced)
boost_test_run(efficiency COMPILE_FLAGS "${RELEASE_COMPILE_FLAGS}")
boost_test_run(maybe)
boost_test_run(deduced)
boost_test_run(optional_deduced_sfinae)
boost_test_run(deduced_dependent_predicate)
boost_test_run(normalized_argument_types)
boost_test_compile(ntp)
boost_test_compile(unwrap_cv_reference)
boost_test_compile_fail(duplicates)
boost_test_compile_fail(deduced_unmatched_arg)
boost_test_compile(compose)
# TODO: [ bpl-test python_test ]

19
test/Jamfile Executable file
View File

@@ -0,0 +1,19 @@
# Boost Parameter Library test Jamfile
subproject libs/parameter/test ;
# bring in rules for testing
import testing ;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run unnamed.cpp ]
[ run earwicker.cpp ]
[ run tutorial.cpp ]
[ run mpl.cpp ]
[ run efficiency.cpp : : : : : release ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
;

View File

@@ -1,11 +1,5 @@
# Copyright David Abrahams, Daniel Wallin 2006. Distributed under the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Boost Parameter Library test Jamfile
import python ;
project boost/parameter
: default-build <warnings>off
;
@@ -14,23 +8,11 @@ test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run earwicker.cpp ]
[ run unnamed.cpp ]
[ run tutorial.cpp ]
[ run singular.cpp ]
[ run earwicker.cpp ]
[ run mpl.cpp ]
[ run preprocessor.cpp ]
[ run preprocessor_deduced.cpp ]
[ run efficiency.cpp : : : : : <variant>release ]
[ run maybe.cpp ]
[ run deduced.cpp ]
[ run optional_deduced_sfinae.cpp ]
[ run deduced_dependent_predicate.cpp ]
[ run normalized_argument_types.cpp ]
[ compile ntp.cpp ]
[ run efficiency.cpp : : : <variant>release ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
[ compile-fail deduced_unmatched_arg.cpp ]
[ compile compose.cpp ]
[ bpl-test python_test ]
;

4
test/basics.cpp Normal file → Executable file
View File

@@ -11,6 +11,7 @@
#include "basics.hpp"
namespace test
{
// A separate function for getting the "value" key, so we can deduce
@@ -106,7 +107,6 @@ int main()
#endif
//f(index = 56, name = 55); // won't compile
return boost::report_errors();
return 0;
}

13
test/basics.hpp Normal file → Executable file
View File

@@ -8,11 +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>
#include <boost/detail/lightweight_test.hpp>
namespace test {
@@ -45,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
@@ -80,9 +79,9 @@ struct values_t
BOOST_MPL_ASSERT((boost::is_same<Value,Value_>));
BOOST_MPL_ASSERT((boost::is_same<Name,Name_>));
#endif
BOOST_TEST(equal(n, n_));
BOOST_TEST(equal(v, v_));
BOOST_TEST(equal(i, i_));
BOOST_ASSERT(equal(n, n_));
BOOST_ASSERT(equal(v, v_));
BOOST_ASSERT(equal(i, i_));
}
Name const& n;

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

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

View File

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

View File

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

View File

@@ -1,25 +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/parameters.hpp>
#include <boost/parameter/name.hpp>
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
int main()
{
using namespace parameter;
using boost::is_convertible;
using mpl::_;
parameters<
optional<
deduced<tag::x>, is_convertible<_,int>
>
>()("foo");
}

2
test/duplicates.cpp Normal file → Executable file
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;

0
test/earwicker.cpp Normal file → Executable file
View File

44
test/efficiency.cpp Normal file → Executable file
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;

0
test/macros.cpp Normal file → Executable file
View File

View File

@@ -1,35 +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);
return 0;
}

16
test/mpl.cpp Normal file → Executable file
View File

@@ -9,7 +9,9 @@
#include <boost/mpl/size.hpp>
#include <boost/type_traits/add_pointer.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/find.hpp>
# include <boost/mpl/end.hpp>
namespace test
{
@@ -21,7 +23,13 @@ namespace test
template <class T>
void operator()(T*)
{
BOOST_MPL_ASSERT((mpl::contains<Set,T>));
#if 1 // mpl::set is too unreliable in this release.
typedef typename mpl::find<Set,T>::type pos;
typedef typename mpl::end<Set>::type not_found;
BOOST_MPL_ASSERT_NOT((boost::is_same<pos, not_found>));
#else
BOOST_MPL_ASSERT((mpl::has_key<Set,T>));
#endif
}
};
@@ -34,7 +42,7 @@ namespace test
, ==
, mpl::size<Params>::value
);
mpl::for_each<Params, boost::add_pointer<mpl::_1> >(assert_in_set<Expected>());
}
@@ -57,6 +65,7 @@ namespace test
f_impl<Expected>(f_parameters()(t, name_));
}
void run()
{
typedef test::tag::tester tester_;
@@ -68,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,85 +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>));
BOOST_MPL_ASSERT((boost::is_same<y_type,int>));
return 0;
}
BOOST_PARAMETER_FUNCTION((int), g, tag,
(required
(x, (count_instances))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances>));
assert(count_instances::count > 0);
return 0;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(x, (count_instances const&))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances const>));
assert(count_instances::count == 1);
return 0;
}
int main()
{
f(1, 2);
f(1., 2.f);
f(1U, 2L);
g(0);
h(0);
}

View File

@@ -1,110 +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::optional<
parameter::deduced<a3_is<> >
, boost::is_base_and_derived<X, mpl::_>
>
>::bind<A0,A1,A2,A3
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, 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<a0_is<int>, Y>::type, void(*)(int,void*,void*, Y)
>));
BOOST_MPL_ASSERT((boost::is_same<
with_ntp<int&, a2_is<char>, Y>::type, void(*)(int&,void*,char, Y)
>));

View File

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

View File

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

View File

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

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

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

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

21
test/sfinae.cpp Normal file → Executable file
View File

@@ -5,11 +5,11 @@
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/assert.hpp>
#include <string>
#include <boost/type_traits/is_convertible.hpp>
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
@@ -38,14 +38,14 @@ namespace test
// vc++ 6 ICE.
void assert_equal_string(std::string x, std::string y)
{
BOOST_TEST(x == y);
BOOST_ASSERT(x == y);
}
template<class P>
void f_impl(P const& p)
{
float v = p[value | 3.f];
BOOST_TEST(v == 3.f);
BOOST_ASSERT(v == 3.f);
assert_equal_string(p[name | "bar"], "foo");
}
@@ -54,6 +54,8 @@ namespace test
f_impl(f_parameters()());
}
using boost::parameter::aux::void_;
template<class A0>
void f(
A0 const& a0
@@ -70,7 +72,7 @@ namespace test
f_impl(args(a0, a1));
}
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
#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
@@ -96,9 +98,10 @@ int main()
f("foo", 3.f);
f(value = 3.f, name = "foo");
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
BOOST_TEST(f(3, 4) == 0);
#endif
return boost::report_errors();
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
}

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

0
test/timings.txt Normal file → Executable file
View File

1
test/tutorial.cpp Normal file → Executable file
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

75
test/unnamed.cpp Executable file
View File

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

0
test/unwrap_cv_reference.cpp Normal file → Executable file
View File