mirror of
https://github.com/boostorg/parameter.git
synced 2026-01-19 16:32:13 +00:00
Compare commits
160 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7981ef509c | ||
|
|
7689b5b9d0 | ||
|
|
a28883d9ad | ||
|
|
45bac7b579 | ||
|
|
e4e6ba52c4 | ||
|
|
6bb4b0ef8b | ||
|
|
e0416b8343 | ||
|
|
f8a1b652bc | ||
|
|
f7611b8a1f | ||
|
|
493a8b28a5 | ||
|
|
32ec272b6d | ||
|
|
4c8c0cce93 | ||
|
|
8fc7ba81cc | ||
|
|
5b2b1a47f8 | ||
|
|
f3764c539e | ||
|
|
b67fbdff8f | ||
|
|
0e263f5602 | ||
|
|
3c815b31fe | ||
|
|
dbbe37b8c1 | ||
|
|
ce712b8f30 | ||
|
|
913fa2eb44 | ||
|
|
12c873d3e4 | ||
|
|
164c48c018 | ||
|
|
2ac8833532 | ||
|
|
6556e278c6 | ||
|
|
1a9e89cb8d | ||
|
|
6d53a2b914 | ||
|
|
c7296b9a05 | ||
|
|
6a5d61ce3c | ||
|
|
e887f199e0 | ||
|
|
e7bd42b07a | ||
|
|
b9248d774f | ||
|
|
763a09c5aa | ||
|
|
07987bc97c | ||
|
|
b59c238a83 | ||
|
|
9dfa5a8d9e | ||
|
|
3d0bdf694c | ||
|
|
b5c6e05ea0 | ||
|
|
cc2a478afc | ||
|
|
1dab8a1008 | ||
|
|
4facdaafc3 | ||
|
|
5190f65321 | ||
|
|
0335832574 | ||
|
|
b9f287ea52 | ||
|
|
28f98ecbf0 | ||
|
|
4e8c8ced0f | ||
|
|
5baef32925 | ||
|
|
cc8ca29980 | ||
|
|
e2405e2d00 | ||
|
|
1cba9bd634 | ||
|
|
e58e928af4 | ||
|
|
c3e842fc4c | ||
|
|
ab57984c04 | ||
|
|
a8dc2bbd25 | ||
|
|
bb838edb2f | ||
|
|
74b777612e | ||
|
|
ea4457878c | ||
|
|
1f3fb08086 | ||
|
|
702ca6af6e | ||
|
|
225a38b68a | ||
|
|
de756246e7 | ||
|
|
de67d5fe6d | ||
|
|
40332972ca | ||
|
|
47292301e7 | ||
|
|
7a5a21dacc | ||
|
|
04aaeef41d | ||
|
|
5a0bad4224 | ||
|
|
07f167eed3 | ||
|
|
b34aa49ceb | ||
|
|
f5dbd06b32 | ||
|
|
9bcd7c2fec | ||
|
|
7f2abce0d4 | ||
|
|
b7036ee04f | ||
|
|
36d25230e6 | ||
|
|
d298a327b5 | ||
|
|
8162166037 | ||
|
|
dbcf8de808 | ||
|
|
07893af4c5 | ||
|
|
2070231553 | ||
|
|
5b1971f1ef | ||
|
|
988bb4b365 | ||
|
|
64bfddc3a7 | ||
|
|
2a0397c1b2 | ||
|
|
decd9ac9fd | ||
|
|
a181afc699 | ||
|
|
a6db5788f6 | ||
|
|
d37e7cd513 | ||
|
|
6dd64214c2 | ||
|
|
96d3e0fd07 | ||
|
|
ac398b0e50 | ||
|
|
3f1f0657f6 | ||
|
|
abae0c8d21 | ||
|
|
892a599999 | ||
|
|
acbf69fdb6 | ||
|
|
566e886887 | ||
|
|
ae05e30eac | ||
|
|
310998435c | ||
|
|
647265bfd3 | ||
|
|
76af708b1f | ||
|
|
deb606ef59 | ||
|
|
721b294842 | ||
|
|
f40418cf9a | ||
|
|
b12dbd9f6a | ||
|
|
6087feef11 | ||
|
|
e7d652f208 | ||
|
|
51c3dd4cb1 | ||
|
|
8cf35658bd | ||
|
|
ee2b252418 | ||
|
|
45d320a434 | ||
|
|
76067ad5d2 | ||
|
|
15b0729181 | ||
|
|
23d30d9ea6 | ||
|
|
012e0abd22 | ||
|
|
225ee5072e | ||
|
|
384add2571 | ||
|
|
05c3161112 | ||
|
|
0fb6393510 | ||
|
|
3449cb1c73 | ||
|
|
d73cee75cf | ||
|
|
4350ac39f5 | ||
|
|
6530322582 | ||
|
|
d1f8f1f736 | ||
|
|
764106fe93 | ||
|
|
4a0c231377 | ||
|
|
20b7423e60 | ||
|
|
296832a99f | ||
|
|
47281b5e61 | ||
|
|
f6dcc4a550 | ||
|
|
cb9530157e | ||
|
|
d21dfd48d8 | ||
|
|
066d950c17 | ||
|
|
2ad4d6a45b | ||
|
|
5f001699f7 | ||
|
|
a6b93eb0af | ||
|
|
9479ed3f91 | ||
|
|
8872100508 | ||
|
|
3b90b4ffa4 | ||
|
|
da78942b0b | ||
|
|
3e0cdfa6ad | ||
|
|
31f38561ac | ||
|
|
4d64b38dad | ||
|
|
9e89160e91 | ||
|
|
88e1488e52 | ||
|
|
e129d30002 | ||
|
|
12da98e683 | ||
|
|
3a5cabb94f | ||
|
|
5c79ce742c | ||
|
|
863158c312 | ||
|
|
2518454e99 | ||
|
|
02735ebc2f | ||
|
|
968a588eed | ||
|
|
d6b6b429be | ||
|
|
10ce44d8cb | ||
|
|
d78e0c8281 | ||
|
|
1e7ca24606 | ||
|
|
cf678265a6 | ||
|
|
6cf2dcbc84 | ||
|
|
edd6439564 | ||
|
|
73eccfc901 | ||
|
|
4aa2996d75 |
24
doc/Jamfile.v2
Executable file
24
doc/Jamfile.v2
Executable file
@@ -0,0 +1,24 @@
|
||||
# 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 ;
|
||||
sources = [ path.glob . : *.rst ] ;
|
||||
bases = $(sources:S=) ;
|
||||
|
||||
# This is a path relative to the html/ subdirectory where the
|
||||
# generated output will eventually be moved.
|
||||
stylesheet = "--stylesheet=rst.css" ;
|
||||
|
||||
for local b in $(bases)
|
||||
{
|
||||
html $(b) : $(b).rst :
|
||||
|
||||
#
|
||||
<docutils-html>"-gdt --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
|
||||
;
|
||||
}
|
||||
|
||||
alias htmls : $(bases) ;
|
||||
stage html : $(bases) ;
|
||||
2193
doc/html/index.html
Executable file
2193
doc/html/index.html
Executable file
File diff suppressed because it is too large
Load Diff
787
doc/html/python.html
Normal file
787
doc/html/python.html
Normal file
@@ -0,0 +1,787 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>The Boost Parameter Library Python Binding Documentation</title>
|
||||
<meta name="authors" content="Daniel Wallin" />
|
||||
<meta name="organization" content="Boost Consulting" />
|
||||
<meta name="date" content="2006-12-14" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Daniel Wallin 2005. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)" />
|
||||
<link rel="stylesheet" href="rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="the-boost-parameter-library-python-binding-documentation">
|
||||
<h1 class="title">The Boost Parameter Library Python Binding Documentation</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Authors:</th>
|
||||
<td>Daniel Wallin</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first last reference" href="mailto:dalwan01@student.umu.se">dalwan01@student.umu.se</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first last reference" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2006-12-14</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Daniel Wallin
|
||||
2005. Distributed under the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="abstract topic">
|
||||
<p class="topic-title first">Abstract</p>
|
||||
<p>Makes it possible to bind Boost.Parameter-enabled
|
||||
functions, operators and constructors to Python.</p>
|
||||
</div>
|
||||
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
|
||||
<div class="contents topic">
|
||||
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id7" name="id7">Introduction</a></li>
|
||||
<li><a class="reference" href="#tutorial" id="id8" name="id8">Tutorial</a></li>
|
||||
<li><a class="reference" href="#concept-parameterspec" id="id9" name="id9">concept <span class="concept">ParameterSpec</span></a></li>
|
||||
<li><a class="reference" href="#special-keywords" id="id10" name="id10"><em>special</em> keywords</a></li>
|
||||
<li><a class="reference" href="#class-template-init" id="id11" name="id11">class template <tt class="docutils literal"><span class="pre">init</span></tt></a></li>
|
||||
<li><a class="reference" href="#class-template-call" id="id12" name="id12">class template <tt class="docutils literal"><span class="pre">call</span></tt></a></li>
|
||||
<li><a class="reference" href="#class-template-function" id="id13" name="id13">class template <tt class="docutils literal"><span class="pre">function</span></tt></a></li>
|
||||
<li><a class="reference" href="#function-template-def" id="id14" name="id14">function template <tt class="docutils literal"><span class="pre">def</span></tt></a></li>
|
||||
<li><a class="reference" href="#portability" id="id15" name="id15">Portability</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id7" id="introduction" name="introduction">Introduction</a></h1>
|
||||
<p><tt class="docutils literal"><span class="pre">boost/parameter/python.hpp</span></tt> introduces a group of <a class="reference" href="../../../python/doc/v2/def_visitor.html"><tt class="docutils literal"><span class="pre">def_visitors</span></tt></a> that can
|
||||
be used to easily expose Boost.Parameter-enabled member functions to Python with
|
||||
Boost.Python. It also provides a function template <tt class="docutils literal"><span class="pre">def()</span></tt> that can be used
|
||||
to expose Boost.Parameter-enabled free functions.</p>
|
||||
<p>When binding a Boost.Parameter enabled function, the keyword tags
|
||||
must be specified. Additionally, because Boost.Parameter enabled
|
||||
functions are templates, the desired function signature must be
|
||||
specified.</p>
|
||||
<!-- The keyword tags are specified as an `MPL Sequence`_, using the
|
||||
pointer qualifications described in |ParameterSpec|_ below. The
|
||||
signature is also specifid as an `MPL sequence`_ of parameter
|
||||
types. Additionally, ``boost::parameter::python::function`` and
|
||||
``boost::parameter::python::def`` requires a class with forwarding
|
||||
overloads. We will take a closer look at how this is done in the
|
||||
tutorial section below. -->
|
||||
<p>The keyword tags and associated argument types are specified as an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL
|
||||
Sequence</a>, using the function type syntax described in <a class="reference" href="#concept-parameterspec"><span class="concept">ParameterSpec</span></a>
|
||||
below. Additionally, <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> and
|
||||
<tt class="docutils literal"><span class="pre">boost::parameter::python::def</span></tt> requires a class with forwarding overloads.
|
||||
We will take a closer look at how this is done in the tutorial section below.</p>
|
||||
<!-- The last two sentences are terribly vague. Which namespace is -->
|
||||
<!-- ``function`` in? Isn't the return type always needed? What -->
|
||||
<!-- else are we going to do other than pass these sequences to -->
|
||||
<!-- function? -->
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id8" id="tutorial" name="tutorial">Tutorial</a></h1>
|
||||
<p>In this section we will outline the steps needed to bind a simple
|
||||
Boost.Parameter-enabled member function to Python. Knowledge of the
|
||||
Boost.Parameter <a class="reference" href="index.html">macros</a> are required to understand this section.</p>
|
||||
<p>The class and member function we are interested in binding looks
|
||||
like this:</p>
|
||||
<pre class="literal-block">
|
||||
#include <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))
|
||||
)
|
||||
{
|
||||
<em>… function implementation …</em>
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<!-- @example.prepend('#include <cassert>') -->
|
||||
<!-- @example.replace_emphasis('''
|
||||
assert(title == "foo");
|
||||
assert(height == 20);
|
||||
assert(width == 400);
|
||||
''') -->
|
||||
<p>It defines a set of overloaded member functions called <tt class="docutils literal"><span class="pre">open</span></tt> with one
|
||||
required parameter and two optional ones. To bind this member function to
|
||||
Python we use the binding utility <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt>.
|
||||
<tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> is a <a class="reference" href="../../../python/doc/v2/def_visitor.html"><tt class="docutils literal"><span class="pre">def_visitor</span></tt></a> that we'll instantiate
|
||||
and pass to <tt class="docutils literal"><span class="pre">boost::python::class_::def()</span></tt>.</p>
|
||||
<p>To use <tt class="docutils literal"><span class="pre">boost::parameter::python::function</span></tt> we first need to define
|
||||
a class with forwarding overloads. 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 <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);
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<p>The first parameter, <tt class="docutils literal"><span class="pre">boost::type<void></span></tt>, tells the forwarding overload
|
||||
what the return type should be. In this case we know that it's always void
|
||||
but in some cases, when we are exporting several specializations of a
|
||||
Boost.Parameter-enabled template, we need to use that parameter to
|
||||
deduce the return type.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">window::open()</span></tt> takes a total of 3 parameters, so the forwarding function
|
||||
needs to take three parameters as well.</p>
|
||||
<div class="note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">We only need one overload in the forwarding class, despite the
|
||||
fact that there are two optional parameters. There are special
|
||||
circumstances when several overload are needed; see
|
||||
<a class="reference" href="#special-keywords">special keywords</a>.</p>
|
||||
</div>
|
||||
<p>Next we'll define the module and export the class:</p>
|
||||
<pre class="literal-block">
|
||||
BOOST_PYTHON_MODULE(my_module)
|
||||
{
|
||||
using namespace boost::python;
|
||||
namespace py = boost::parameter::python;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
class_<window>("window")
|
||||
.def(
|
||||
"open", py::function<
|
||||
open_fwd
|
||||
, mpl::vector<
|
||||
void
|
||||
, tag::title(std::string)
|
||||
, tag::width*(unsigned)
|
||||
, tag::height*(unsigned)
|
||||
>
|
||||
>()
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
<!-- @jam_prefix.append('import python ;') -->
|
||||
<!-- @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') -->
|
||||
<!-- @my_module = build(
|
||||
output = 'my_module'
|
||||
, target_rule = 'python-extension'
|
||||
, input = '/boost/python//boost_python'
|
||||
, howmany = 'all'
|
||||
) -->
|
||||
<!-- @del jam_prefix[:] -->
|
||||
<p><tt class="docutils literal"><span class="pre">py::function</span></tt> is passed two parameters. The first one is the class with
|
||||
forwarding overloads that we defined earlier. The second one is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL
|
||||
Sequence</a> with the keyword tag types and argument types for the function
|
||||
specified as function types. The pointer syntax used in <tt class="docutils literal"><span class="pre">tag::width*</span></tt> and
|
||||
<tt class="docutils literal"><span class="pre">tag::height*</span></tt> means that the parameter is optional. The first element of
|
||||
the <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a> is the return type of the function, in this case <tt class="docutils literal"><span class="pre">void</span></tt>,
|
||||
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">
|
||||
>>> w = my_module.window()
|
||||
>>> w.open(title = "foo", height = 20)
|
||||
</pre>
|
||||
<!-- @example.prepend('import my_module') -->
|
||||
<!-- @run_python(module_path = my_module) -->
|
||||
<!-- Sorry to say this at such a late date, but this syntax really -->
|
||||
<!-- strikes me as cumbersome. Couldn't we do something like:
|
||||
|
||||
class_<window>("window")
|
||||
.def(
|
||||
"open",
|
||||
(void (*)(
|
||||
tag::title(std::string),
|
||||
tag::width*(unsigned),
|
||||
tag::height*(unsigned))
|
||||
)0
|
||||
);
|
||||
|
||||
or at least:
|
||||
|
||||
class_<window>("window")
|
||||
.def(
|
||||
"open",
|
||||
mpl::vector<
|
||||
void,
|
||||
tag::title(std::string),
|
||||
tag::width*(unsigned),
|
||||
tag::height*(unsigned)
|
||||
>()
|
||||
);
|
||||
|
||||
assuming, that is, that we will have to repeat the tags (yes,
|
||||
users of broken compilers will have to give us function pointer
|
||||
types instead). -->
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id9" id="concept-parameterspec" name="concept-parameterspec">concept <span class="concept">ParameterSpec</span></a></h1>
|
||||
<p>A <span class="concept">ParameterSpec</span> is a function type <tt class="docutils literal"><span class="pre">K(T)</span></tt> that describes both the keyword tag,
|
||||
<tt class="docutils literal"><span class="pre">K</span></tt>, and the argument type, <tt class="docutils literal"><span class="pre">T</span></tt>, for a parameter.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">K</span></tt> is either:</p>
|
||||
<ul class="simple">
|
||||
<li>A <em>required</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag</span></tt></li>
|
||||
<li><strong>or</strong>, an <em>optional</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag*</span></tt></li>
|
||||
<li><strong>or</strong>, a <em>special</em> keyword of the form <tt class="docutils literal"><span class="pre">Tag**</span></tt></li>
|
||||
</ul>
|
||||
<p>where <tt class="docutils literal"><span class="pre">Tag</span></tt> is a keyword tag type, as used in a specialization
|
||||
of <a class="reference" href="../../../parameter/doc/html/reference.html#keyword"><tt class="docutils literal"><span class="pre">boost::parameter::keyword</span></tt></a>.</p>
|
||||
<p>The <strong>arity range</strong> for an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL Sequence</a> of <span class="concept">ParameterSpec</span>'s is
|
||||
defined as the closed range:</p>
|
||||
<pre class="literal-block">
|
||||
[ mpl::size<S> - number of <em>special</em> keyword tags in <tt class="docutils literal"><span class="pre">S</span></tt>, mpl::size<S> ]
|
||||
</pre>
|
||||
<p>For example, the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">mpl::vector2<x(int),y(int)></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<x(int),y*(int)></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<x(int),y**(int)></span></tt> is <tt class="docutils literal"><span class="pre">[1,2]</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id10" id="special-keywords" name="special-keywords"><em>special</em> keywords</a></h1>
|
||||
<p>Sometimes it is desirable to have a default value for a parameter that differ
|
||||
in type from the parameter. This technique is useful for doing simple tag-dispatching
|
||||
based on the presence of a parameter. 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 <class ArgumentPack>
|
||||
void dfs_dispatch(ArgumentPack const& args, mpl::false_)
|
||||
{
|
||||
<em>…compute and use default color map…</em>
|
||||
}
|
||||
|
||||
template <class ArgumentPack, class ColorMap>
|
||||
void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
|
||||
{
|
||||
<em>…use colormap…</em>
|
||||
}
|
||||
}
|
||||
|
||||
template <class ArgumentPack>
|
||||
void depth_first_search(ArgumentPack const& 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" 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">
|
||||
<h1><a class="toc-backref" href="#id11" id="class-template-init" name="class-template-init">class template <tt class="docutils literal"><span class="pre">init</span></tt></a></h1>
|
||||
<p>Defines a named parameter enabled constructor.</p>
|
||||
<pre class="literal-block">
|
||||
template <class ParameterSpecs>
|
||||
struct init : python::def_visitor<init<ParameterSpecs> >
|
||||
{
|
||||
template <class Class>
|
||||
void def(Class& class_);
|
||||
|
||||
template <class CallPolicies>
|
||||
<em>def_visitor</em> operator[](CallPolicies const& policies) const;
|
||||
};
|
||||
</pre>
|
||||
<!-- @ignore() -->
|
||||
<div class="section">
|
||||
<h2><a id="init-requirements" name="init-requirements"><tt class="docutils literal"><span class="pre">init</span></tt> requirements</a></h2>
|
||||
<ul>
|
||||
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element is a
|
||||
model of <span class="concept">ParameterSpec</span>.</p>
|
||||
</li>
|
||||
<li><p class="first">For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity
|
||||
range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>, <tt class="docutils literal"><span class="pre">Class</span></tt> must support these
|
||||
expressions:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="30%" />
|
||||
<col width="17%" />
|
||||
<col width="53%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head"><p class="first last">Expression</p>
|
||||
</th>
|
||||
<th class="head"><p class="first last">Return type</p>
|
||||
</th>
|
||||
<th class="head"><p class="first last">Requirements</p>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">Class(a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last">-</p>
|
||||
</td>
|
||||
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt>…<tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="template-class-callpolicies-operator-callpolicies-const" name="template-class-callpolicies-operator-callpolicies-const"><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">CallPolicies></span> <span class="pre">operator[](CallPolicies</span> <span class="pre">const&)</span></tt></a></h2>
|
||||
<p>Returns a <tt class="docutils literal"><span class="pre">def_visitor</span></tt> equivalent to <tt class="docutils literal"><span class="pre">*this</span></tt>, except that it
|
||||
uses CallPolicies when creating the binding.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="example" name="example">Example</a></h2>
|
||||
<pre class="literal-block">
|
||||
#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)
|
||||
{
|
||||
<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_<X>("X", no_init)
|
||||
.def(
|
||||
py::init<
|
||||
mpl::vector<tag::x(int), tag::y*(int)>
|
||||
>()
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
<!-- @example.replace_emphasis('''
|
||||
assert(args[x] == 0);
|
||||
assert(args[y | 1] == 1);
|
||||
''') -->
|
||||
<!-- @example.replace_emphasis('my_module') -->
|
||||
<!-- @jam_prefix.append('import python ;') -->
|
||||
<!-- @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') -->
|
||||
<!-- @my_module = build(
|
||||
output = 'my_module'
|
||||
, target_rule = 'python-extension'
|
||||
, input = '/boost/python//boost_python'
|
||||
) -->
|
||||
</div>
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id12" id="class-template-call" name="class-template-call">class template <tt class="docutils literal"><span class="pre">call</span></tt></a></h1>
|
||||
<p>Defines a <tt class="docutils literal"><span class="pre">__call__</span></tt> operator, mapped to <tt class="docutils literal"><span class="pre">operator()</span></tt> in C++.</p>
|
||||
<pre class="literal-block">
|
||||
template <class ParameterSpecs>
|
||||
struct call : python::def_visitor<call<ParameterSpecs> >
|
||||
{
|
||||
template <class Class>
|
||||
void def(Class& class_);
|
||||
|
||||
template <class CallPolicies>
|
||||
<em>def_visitor</em> operator[](CallPolicies const& policies) const;
|
||||
};
|
||||
</pre>
|
||||
<!-- @ignore() -->
|
||||
<div class="section">
|
||||
<h2><a id="call-requirements" name="call-requirements"><tt class="docutils literal"><span class="pre">call</span></tt> requirements</a></h2>
|
||||
<ul>
|
||||
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
|
||||
except the first models <span class="concept">ParameterSpec</span>. The first element
|
||||
is the result type of <tt class="docutils literal"><span class="pre">c(…)</span></tt>.</p>
|
||||
</li>
|
||||
<li><p class="first"><tt class="docutils literal"><span class="pre">Class</span></tt> must support these expressions, where <tt class="docutils literal"><span class="pre">c</span></tt> is an
|
||||
instance of <tt class="docutils literal"><span class="pre">Class</span></tt>:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="24%" />
|
||||
<col width="26%" />
|
||||
<col width="50%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head"><p class="first last">Expression</p>
|
||||
</th>
|
||||
<th class="head"><p class="first last">Return type</p>
|
||||
</th>
|
||||
<th class="head"><p class="first last">Requirements</p>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><p class="first last"><tt class="docutils literal"><span class="pre">c(a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt>…<tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id3" name="id3"><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">CallPolicies></span> <span class="pre">operator[](CallPolicies</span> <span class="pre">const&)</span></tt></a></h2>
|
||||
<p>Returns a <tt class="docutils literal"><span class="pre">def_visitor</span></tt> equivalent to <tt class="docutils literal"><span class="pre">*this</span></tt>, except that it
|
||||
uses CallPolicies when creating the binding.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id4" name="id4">Example</a></h2>
|
||||
<pre class="literal-block">
|
||||
#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)
|
||||
{
|
||||
<em>… use args …</em>
|
||||
}
|
||||
|
||||
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(<em>module name</em>)
|
||||
{
|
||||
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)>
|
||||
>()
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
<!-- @example.replace_emphasis('''
|
||||
assert(args[x] == 0);
|
||||
assert(args[y | 1] == 1);
|
||||
return 0;
|
||||
''') -->
|
||||
<!-- @example.replace_emphasis('my_module') -->
|
||||
<!-- @my_module = build(
|
||||
output = 'my_module'
|
||||
, target_rule = 'python-extension'
|
||||
, input = '/boost/python//boost_python'
|
||||
) -->
|
||||
</div>
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id13" id="class-template-function" name="class-template-function">class template <tt class="docutils literal"><span class="pre">function</span></tt></a></h1>
|
||||
<p>Defines a named parameter enabled member function.</p>
|
||||
<pre class="literal-block">
|
||||
template <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);
|
||||
};
|
||||
</pre>
|
||||
<!-- @ignore() -->
|
||||
<div class="section">
|
||||
<h2><a id="function-requirements" name="function-requirements"><tt class="docutils literal"><span class="pre">function</span></tt> requirements</a></h2>
|
||||
<ul>
|
||||
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
|
||||
except the first models <span class="concept">ParameterSpec</span>. The first element
|
||||
is the result type of <tt class="docutils literal"><span class="pre">c.f(…)</span></tt>, where <tt class="docutils literal"><span class="pre">f</span></tt> is the member
|
||||
function.</p>
|
||||
</li>
|
||||
<li><p class="first">An instance of <tt class="docutils literal"><span class="pre">Fwd</span></tt> must support this expression:</p>
|
||||
<table border="1" class="docutils">
|
||||
<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<R>(),</span> <span class="pre">self,</span> <span class="pre">a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last"><tt class="docutils literal"><span class="pre">self</span></tt> is a reference to the object on which
|
||||
the function should be invoked. <tt class="docutils literal"><span class="pre">a0</span></tt>…<tt class="docutils literal"><span class="pre">aN</span></tt>
|
||||
are tagged arguments.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id5" name="id5">Example</a></h2>
|
||||
<p>This example exports a member function <tt class="docutils literal"><span class="pre">f(int</span> <span class="pre">x,</span> <span class="pre">int</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">…)</span></tt> to Python. The
|
||||
sequence of <span class="concept">ParameterSpec</span>'s <tt class="docutils literal"><span class="pre">mpl::vector2<tag::x(int),</span> <span class="pre">tag::y*(int)></span></tt> has
|
||||
an <strong>arity range</strong> of [2,2], so we only need one forwarding overload.</p>
|
||||
<pre class="literal-block">
|
||||
#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))
|
||||
)
|
||||
{
|
||||
<em>…</em>
|
||||
}
|
||||
};
|
||||
|
||||
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(<em>module name</em>)
|
||||
{
|
||||
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)>
|
||||
>()
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
<!-- @example.replace_emphasis('''
|
||||
assert(x == 0);
|
||||
assert(y == 1);
|
||||
''') -->
|
||||
<!-- @example.replace_emphasis('my_module') -->
|
||||
<!-- @my_module = build(
|
||||
output = 'my_module'
|
||||
, target_rule = 'python-extension'
|
||||
, input = '/boost/python//boost_python'
|
||||
) -->
|
||||
</div>
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id14" id="function-template-def" name="function-template-def">function template <tt class="docutils literal"><span class="pre">def</span></tt></a></h1>
|
||||
<p>Defines a named parameter enabled free function in the current Python scope.</p>
|
||||
<pre class="literal-block">
|
||||
template <class Fwd, class ParameterSpecs>
|
||||
void def(char const* name);
|
||||
</pre>
|
||||
<!-- @ignore() -->
|
||||
<div class="section">
|
||||
<h2><a id="def-requirements" name="def-requirements"><tt class="docutils literal"><span class="pre">def</span></tt> requirements</a></h2>
|
||||
<ul>
|
||||
<li><p class="first"><tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt> is an <a class="reference" href="../../../mpl/doc/refmanual/sequences.html">MPL sequence</a> where each element
|
||||
except the first models <span class="concept">ParameterSpec</span>. The first element
|
||||
is the result type of <tt class="docutils literal"><span class="pre">f(…)</span></tt>, where <tt class="docutils literal"><span class="pre">f</span></tt> is the function.</p>
|
||||
</li>
|
||||
<li><p class="first">An instance of <tt class="docutils literal"><span class="pre">Fwd</span></tt> must support this expression:</p>
|
||||
<table border="1" class="docutils">
|
||||
<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<R>(),</span> <span class="pre">a0,</span> <span class="pre">…,</span> <span class="pre">aN)</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last">Convertible to <tt class="docutils literal"><span class="pre">R</span></tt></p>
|
||||
</td>
|
||||
<td><p class="first last"><tt class="docutils literal"><span class="pre">a0</span></tt>…<tt class="docutils literal"><span class="pre">aN</span></tt> are tagged arguments.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>For every <tt class="docutils literal"><span class="pre">N</span></tt> in <tt class="docutils literal"><span class="pre">[U,V]</span></tt>, where <tt class="docutils literal"><span class="pre">[U,V]</span></tt> is the <strong>arity range</strong> of <tt class="docutils literal"><span class="pre">ParameterSpecs</span></tt>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id6" name="id6">Example</a></h2>
|
||||
<p>This example exports a function <tt class="docutils literal"><span class="pre">f(int</span> <span class="pre">x,</span> <span class="pre">int</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">…)</span></tt> to Python. The
|
||||
sequence of <span class="concept">ParameterSpec</span>'s <tt class="docutils literal"><span class="pre">mpl::vector2<tag::x(int),</span> <span class="pre">tag::y*(int)></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 <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");
|
||||
}
|
||||
</pre>
|
||||
<!-- @ignore() -->
|
||||
<!-- again, the undefined ``fwd`` identifier. -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a class="toc-backref" href="#id15" id="portability" name="portability">Portability</a></h1>
|
||||
<p>The Boost.Parameter Python binding library requires <em>partial template
|
||||
specialization</em>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<hr class="footer" />
|
||||
Generated on: 2007-01-03 16:40 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1136
doc/html/reference.html
Executable file
1136
doc/html/reference.html
Executable file
File diff suppressed because it is too large
Load Diff
43
doc/html/rst.css
Executable file
43
doc/html/rst.css
Executable file
@@ -0,0 +1,43 @@
|
||||
/* 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 {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
td span {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
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 ;
|
||||
}
|
||||
|
||||
CODE
|
||||
{
|
||||
FONT-FAMILY: monospace;
|
||||
}
|
||||
.pre
|
||||
{
|
||||
FONT-FAMILY: monospace;
|
||||
}
|
||||
BIN
doc/html/vellipsis.gif
Executable file
BIN
doc/html/vellipsis.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 62 B |
2351
doc/index.rst
Executable file
2351
doc/index.rst
Executable file
File diff suppressed because it is too large
Load Diff
778
doc/python.rst
Executable file
778
doc/python.rst
Executable file
@@ -0,0 +1,778 @@
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
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*.
|
||||
|
||||
1001
doc/reference.rst
Executable file
1001
doc/reference.rst
Executable file
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,11 @@
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
#include <boost/parameter/value_type.hpp>
|
||||
#include <boost/parameter/macros.hpp>
|
||||
#include <boost/parameter/match.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/parameter/preprocessor.hpp>
|
||||
|
||||
#endif // BOOST_PARAMETER_050401_HPP
|
||||
|
||||
|
||||
@@ -6,18 +6,25 @@
|
||||
#ifndef ARG_LIST_050329_HPP
|
||||
#define ARG_LIST_050329_HPP
|
||||
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
|
||||
#include <boost/parameter/aux_/void.hpp>
|
||||
#include <boost/parameter/aux_/result_of0.hpp>
|
||||
#include <boost/parameter/aux_/default.hpp>
|
||||
#include <boost/parameter/aux_/parameter_requirements.hpp>
|
||||
#include <boost/parameter/aux_/yesno.hpp>
|
||||
#include <boost/parameter/config.hpp>
|
||||
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/iterator_tags.hpp>
|
||||
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
|
||||
namespace boost { namespace parameter {
|
||||
|
||||
// Forward declaration for aux::arg_list, below.
|
||||
@@ -25,6 +32,9 @@ template<class T> struct keyword;
|
||||
|
||||
namespace aux {
|
||||
|
||||
// Tag type passed to MPL lambda.
|
||||
struct lambda_tag;
|
||||
|
||||
//
|
||||
// Structures used to build the tuple of actual arguments. The
|
||||
// tuple is a nested cons-style list of arg_list specializations
|
||||
@@ -36,9 +46,13 @@ namespace aux {
|
||||
// match against keywords.
|
||||
//
|
||||
|
||||
// MPL sequence support
|
||||
struct arg_list_tag;
|
||||
|
||||
// Terminates arg_list<> and represents an empty list. Since this
|
||||
// is just the terminating case you might want to look at arg_list
|
||||
// first, to get a feel for what's really happening here.
|
||||
|
||||
struct empty_arg_list
|
||||
{
|
||||
empty_arg_list() {}
|
||||
@@ -56,13 +70,19 @@ struct empty_arg_list
|
||||
// lookup given that default
|
||||
struct binding
|
||||
{
|
||||
template<class KW, class Default>
|
||||
template<class KW, class Default, class Reference>
|
||||
struct apply
|
||||
{
|
||||
typedef Default type;
|
||||
};
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// Terminator for has_key, indicating that the keyword is unique
|
||||
template <class KW>
|
||||
static no_tag has_key(KW*);
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| (BOOST_WORKAROUND(__GNUC__, < 3)) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
@@ -120,23 +140,60 @@ struct empty_arg_list
|
||||
// was found if we match this overload, so unless that parameter
|
||||
// has a default, we indicate that the actual arguments don't
|
||||
// match the function's requirements.
|
||||
template <class ParameterRequirements>
|
||||
template <class ParameterRequirements, class ArgPack>
|
||||
static typename ParameterRequirements::has_default
|
||||
satisfies(ParameterRequirements*);
|
||||
satisfies(ParameterRequirements*, ArgPack*);
|
||||
|
||||
// MPL sequence support
|
||||
typedef empty_arg_list type; // convenience
|
||||
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
template<class KW>
|
||||
no_tag operator*(empty_arg_list, KW*);
|
||||
#endif
|
||||
|
||||
// Forward declaration for arg_list::operator,
|
||||
template <class KW, class T>
|
||||
struct tagged_argument;
|
||||
|
||||
// Forward declaration for arg_list::operator[], with
|
||||
// IS_XXX helper
|
||||
struct maybe_base;
|
||||
|
||||
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>
|
||||
struct arg_list : Next
|
||||
{
|
||||
typedef arg_list<TaggedArg,Next> self;
|
||||
typedef typename TaggedArg::key_type key_type;
|
||||
typedef typename TaggedArg::value_type value_type;
|
||||
typedef typename TaggedArg::reference reference;
|
||||
|
||||
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;
|
||||
|
||||
TaggedArg arg; // Stores the argument
|
||||
|
||||
@@ -144,12 +201,12 @@ struct arg_list : Next
|
||||
template< // class A0, class A1, ...
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
|
||||
>
|
||||
arg_list( // A0 const& a0, A1 const& a1, ...
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, const & a)
|
||||
arg_list( // A0& a0, A1& a1, ...
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & a)
|
||||
)
|
||||
: Next( // a1, a2, ...
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
|
||||
, void_()
|
||||
, void_reference()
|
||||
)
|
||||
, arg(a0)
|
||||
{}
|
||||
@@ -162,28 +219,61 @@ 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>
|
||||
template <class KW, class Default, class Reference>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
boost::is_same<KW, key_type>
|
||||
, mpl::identity<reference>
|
||||
, mpl::apply_wrap2<typename Next::binding, KW, Default>
|
||||
, mpl::if_<Reference, reference, value_type>
|
||||
, mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
friend yes_tag operator*(arg_list, key_type*);
|
||||
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) (*(next*)0 * (key*)0)
|
||||
# else
|
||||
// Overload for key_type, so the assert below will fire if the
|
||||
// same keyword is used again
|
||||
static yes_tag has_key(key_type*);
|
||||
using Next::has_key;
|
||||
|
||||
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
|
||||
# endif
|
||||
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
sizeof(BOOST_PARAMETER_CALL_HAS_KEY(Next,key_type)) == sizeof(no_tag)
|
||||
, duplicate_keyword, (key_type)
|
||||
);
|
||||
|
||||
# undef BOOST_PARAMETER_CALL_HAS_KEY
|
||||
#endif
|
||||
//
|
||||
// Begin implementation of indexing operators for looking up
|
||||
// specific arguments by name
|
||||
//
|
||||
|
||||
// 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))
|
||||
@@ -210,7 +300,7 @@ struct arg_list : Next
|
||||
// Outer indexing operators that dispatch to the right node's
|
||||
// get() function.
|
||||
template <class KW>
|
||||
typename mpl::apply_wrap2<binding, KW, void_>::type
|
||||
typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
|
||||
operator[](keyword<KW> const& x) const
|
||||
{
|
||||
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
|
||||
@@ -218,7 +308,7 @@ struct arg_list : Next
|
||||
}
|
||||
|
||||
template <class KW, class Default>
|
||||
typename mpl::apply_wrap2<binding, KW, Default&>::type
|
||||
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
|
||||
operator[](default_<KW, Default> x) const
|
||||
{
|
||||
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
|
||||
@@ -226,9 +316,10 @@ struct arg_list : Next
|
||||
}
|
||||
|
||||
template <class KW, class F>
|
||||
typename mpl::apply_wrap2<
|
||||
typename mpl::apply_wrap3<
|
||||
binding,KW
|
||||
, typename result_of0<F>::type
|
||||
, mpl::true_
|
||||
>::type
|
||||
operator[](lazy_default<KW,F> x) const
|
||||
{
|
||||
@@ -240,38 +331,40 @@ struct arg_list : Next
|
||||
// reached, indicating no matching argument was passed, the
|
||||
// default is returned, or if no default_ or lazy_default was
|
||||
// passed, compilation fails.
|
||||
reference get(keyword<key_type> const& x) const
|
||||
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> x) const
|
||||
reference get(default_<key_type,Default> const& d) const
|
||||
{
|
||||
return arg.value;
|
||||
return get_default(d, holds_maybe());
|
||||
}
|
||||
|
||||
template <class Default>
|
||||
reference get(lazy_default<key_type, Default> x) const
|
||||
reference get(lazy_default<key_type, Default>) const
|
||||
{
|
||||
return arg.value;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
reference operator[](keyword<key_type> const& x) const
|
||||
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> x) const
|
||||
reference operator[](default_<key_type, Default> const& d) const
|
||||
{
|
||||
return arg.value;
|
||||
return get_default(d, holds_maybe());
|
||||
}
|
||||
|
||||
template <class Default>
|
||||
reference operator[](lazy_default<key_type, Default> x) const
|
||||
reference operator[](lazy_default<key_type, Default>) const
|
||||
{
|
||||
return arg.value;
|
||||
}
|
||||
@@ -292,10 +385,14 @@ struct arg_list : Next
|
||||
// compile-time computation and never really called, so a
|
||||
// declaration is enough.
|
||||
//
|
||||
template <class HasDefault, class Predicate>
|
||||
static typename mpl::apply1<Predicate, value_type>::type
|
||||
template <class HasDefault, class Predicate, class ArgPack>
|
||||
static typename mpl::apply_wrap2<
|
||||
typename mpl::lambda<Predicate, lambda_tag>::type
|
||||
, value_type, ArgPack
|
||||
>::type
|
||||
satisfies(
|
||||
parameter_requirements<key_type,Predicate,HasDefault>*
|
||||
, ArgPack*
|
||||
);
|
||||
|
||||
// Builds an overload set including satisfies functions defined
|
||||
@@ -303,23 +400,68 @@ struct arg_list : Next
|
||||
using Next::satisfies;
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
|
||||
// Comma operator to compose argument list without using parameters<>.
|
||||
// Useful for argument lists with undetermined length.
|
||||
template <class KW, class T2>
|
||||
arg_list<tagged_argument<KW, T2>, arg_list>
|
||||
operator,(tagged_argument<KW, T2> x) const
|
||||
arg_list<tagged_argument<KW, T2>, self>
|
||||
operator,(tagged_argument<KW,T2> x) const
|
||||
{
|
||||
return arg_list<tagged_argument<KW, T2>, arg_list>(x, *this);
|
||||
return arg_list<tagged_argument<KW,T2>, self>(x, *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
// MPL sequence support
|
||||
typedef self type; // Convenience for users
|
||||
typedef Next tail_type; // For the benefit of iterators
|
||||
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
|
||||
template <> struct arg_list<int,int> {};
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
// MPL sequence support
|
||||
template <class ArgumentPack>
|
||||
struct arg_list_iterator
|
||||
{
|
||||
typedef mpl::forward_iterator_tag category;
|
||||
|
||||
// The incremented iterator
|
||||
typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
|
||||
|
||||
// dereferencing yields the key type
|
||||
typedef typename ArgumentPack::key_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_list_iterator<empty_arg_list> {};
|
||||
|
||||
}} // namespace parameter::aux
|
||||
|
||||
// MPL sequence support
|
||||
namespace mpl
|
||||
{
|
||||
template <>
|
||||
struct begin_impl<parameter::aux::arg_list_tag>
|
||||
{
|
||||
template <class S>
|
||||
struct apply
|
||||
{
|
||||
typedef parameter::aux::arg_list_iterator<S> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_impl<parameter::aux::arg_list_tag>
|
||||
{
|
||||
template <class>
|
||||
struct apply
|
||||
{
|
||||
typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // ARG_LIST_050329_HPP
|
||||
|
||||
|
||||
129
include/boost/parameter/aux_/cast.hpp
Executable file
129
include/boost/parameter/aux_/cast.hpp
Executable file
@@ -0,0 +1,129 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_CAST_060902_HPP
|
||||
# define BOOST_PARAMETER_CAST_060902_HPP
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/type_traits/remove_const.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
struct use_default_tag {};
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
|
||||
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value
|
||||
|
||||
# else
|
||||
|
||||
// Handles possible implicit casts. Used by preprocessor.hpp to
|
||||
// normalize user input.
|
||||
//
|
||||
// cast<void*>::execute() is identity
|
||||
// cast<void*(X)>::execute() is identity
|
||||
// cast<void(X)>::execute() casts to X
|
||||
//
|
||||
// preprocessor.hpp uses this like this:
|
||||
//
|
||||
// #define X(value, predicate)
|
||||
// cast<void predicate>::execute(value)
|
||||
//
|
||||
// X(something, *)
|
||||
// X(something, *(predicate))
|
||||
// X(something, (int))
|
||||
|
||||
template <class T>
|
||||
struct cast;
|
||||
|
||||
template <>
|
||||
struct cast<void*>
|
||||
{
|
||||
static use_default_tag execute(use_default_tag)
|
||||
{
|
||||
return use_default_tag();
|
||||
}
|
||||
|
||||
static use_default_tag remove_const(use_default_tag)
|
||||
{
|
||||
return use_default_tag();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static U& execute(U& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static U& remove_const(U& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
|
||||
|
||||
typedef void* voidstar;
|
||||
|
||||
template <class T>
|
||||
struct cast<voidstar(T)>
|
||||
: cast<void*>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
struct cast<void*(T)>
|
||||
: cast<void*>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct cast<void(T)>
|
||||
{
|
||||
typedef typename boost::add_reference<
|
||||
typename boost::remove_const<T>::type
|
||||
>::type reference;
|
||||
|
||||
static use_default_tag execute(use_default_tag)
|
||||
{
|
||||
return use_default_tag();
|
||||
}
|
||||
|
||||
static use_default_tag remove_const(use_default_tag)
|
||||
{
|
||||
return use_default_tag();
|
||||
}
|
||||
|
||||
static T execute(T value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static reference remove_const(U const& x)
|
||||
{
|
||||
return const_cast<reference>(x);
|
||||
}
|
||||
};
|
||||
|
||||
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) \
|
||||
boost::parameter::aux::cast<void predicate>::remove_const( \
|
||||
boost::parameter::aux::cast<void predicate>::execute(value) \
|
||||
)
|
||||
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
#endif // BOOST_PARAMETER_CAST_060902_HPP
|
||||
|
||||
98
include/boost/parameter/aux_/maybe.hpp
Executable file
98
include/boost/parameter/aux_/maybe.hpp
Executable file
@@ -0,0 +1,98 @@
|
||||
// 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_MAYBE_060211_HPP
|
||||
# define BOOST_PARAMETER_MAYBE_060211_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>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
struct maybe_base {};
|
||||
|
||||
template <class T>
|
||||
struct maybe : maybe_base
|
||||
{
|
||||
typedef typename add_reference<
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
T const
|
||||
# else
|
||||
typename add_const<T>::type
|
||||
# endif
|
||||
>::type reference;
|
||||
|
||||
typedef typename remove_cv<
|
||||
BOOST_DEDUCED_TYPENAME remove_reference<reference>::type
|
||||
>::type non_cv_value;
|
||||
|
||||
explicit maybe(T value)
|
||||
: value(value)
|
||||
, constructed(false)
|
||||
{}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
typedef reference(maybe<T>::*safe_bool)() const;
|
||||
|
||||
operator safe_bool() const
|
||||
{
|
||||
return value ? &maybe<T>::get : 0 ;
|
||||
}
|
||||
|
||||
reference get() const
|
||||
{
|
||||
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
|
||||
|
||||
@@ -44,29 +44,40 @@
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
#define BOOST_PARAMETER_open_list(z, n, text) \
|
||||
aux::make_arg_list< \
|
||||
aux::item< \
|
||||
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n)
|
||||
|
||||
#define BOOST_PARAMETER_close_list(z, n, text) >
|
||||
|
||||
#define BOOST_PARAMETER_arg_list(n) \
|
||||
mpl::apply_wrap1< \
|
||||
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
|
||||
, mpl::always<aux::empty_arg_list> \
|
||||
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \
|
||||
, unnamed_list>
|
||||
aux::make_arg_list< \
|
||||
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
|
||||
, void_ \
|
||||
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \
|
||||
, deduced_list \
|
||||
, aux::tag_keyword_arg \
|
||||
>
|
||||
|
||||
#define BOOST_PARAMETER_arg_pack_init(z, n, limit) \
|
||||
BOOST_PP_CAT(a, BOOST_PP_SUB(limit,n))
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS(N, class A)>
|
||||
typename BOOST_PARAMETER_arg_list(N)::type
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const
|
||||
typename mpl::first<
|
||||
typename BOOST_PARAMETER_arg_list(N)::type
|
||||
>::type
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, & a)) const
|
||||
{
|
||||
typedef typename BOOST_PARAMETER_arg_list(N)::type arg_tuple;
|
||||
typedef typename BOOST_PARAMETER_arg_list(N)::type result;
|
||||
|
||||
return arg_tuple(
|
||||
BOOST_PP_ENUM_PARAMS(N, a)
|
||||
typedef typename mpl::first<result>::type result_type;
|
||||
typedef typename mpl::second<result>::type error;
|
||||
error();
|
||||
|
||||
return result_type(
|
||||
BOOST_PP_ENUM(N, BOOST_PARAMETER_arg_pack_init, BOOST_PP_DEC(N))
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(
|
||||
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N)
|
||||
, aux::void_() BOOST_PP_INTERCEPT
|
||||
, aux::void_reference() BOOST_PP_INTERCEPT
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
119
include/boost/parameter/aux_/parenthesized_type.hpp
Executable file
119
include/boost/parameter/aux_/parenthesized_type.hpp
Executable file
@@ -0,0 +1,119 @@
|
||||
// Copyright David Abrahams 2006. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
|
||||
# define BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
// A macro that takes a parenthesized C++ type name (T) and transforms
|
||||
// it into an un-parenthesized type expression equivalent to T.
|
||||
# define BOOST_PARAMETER_PARENTHESIZED_TYPE(x) \
|
||||
boost::parameter::aux::unaryfunptr_arg_type< void(*)x >::type
|
||||
|
||||
// A metafunction that transforms void(*)(T) -> T
|
||||
template <class UnaryFunctionPointer>
|
||||
struct unaryfunptr_arg_type;
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
|
||||
template <class Arg>
|
||||
struct unaryfunptr_arg_type<void(*)(Arg)>
|
||||
{
|
||||
typedef Arg type;
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
// Use the "native typeof" bugfeatures of older versions of MSVC to
|
||||
// accomplish what we'd normally do with partial specialization. This
|
||||
// capability was discovered by Igor Chesnokov.
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, != 1300)
|
||||
|
||||
// This version applies to VC6.5 and VC7.1 (except that we can just
|
||||
// use partial specialization for the latter in this case).
|
||||
|
||||
// This gets used as a base class.
|
||||
template<typename Address>
|
||||
struct msvc_type_memory
|
||||
{
|
||||
// A nullary metafunction that will yield the Value type "stored"
|
||||
// at this Address.
|
||||
struct storage;
|
||||
};
|
||||
|
||||
template<typename Value, typename Address>
|
||||
struct msvc_store_type : msvc_type_memory<Address>
|
||||
{
|
||||
// VC++ somehow lets us define the base's nested storage
|
||||
// metafunction here, where we have the Value type we'd like to
|
||||
// "store" in it. Later we can come back to the base class and
|
||||
// extract the "stored type."
|
||||
typedef msvc_type_memory<Address> location;
|
||||
struct location::storage
|
||||
{
|
||||
typedef Value type;
|
||||
};
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
// This slightly more complicated version of the same thing is
|
||||
// required for msvc-7.0
|
||||
template<typename Address>
|
||||
struct msvc_type_memory
|
||||
{
|
||||
template<bool>
|
||||
struct storage_impl;
|
||||
|
||||
typedef storage_impl<true> storage;
|
||||
};
|
||||
|
||||
template<typename Value, typename Address>
|
||||
struct msvc_store_type : msvc_type_memory<Address>
|
||||
{
|
||||
// Rather than supplying a definition for the base class' nested
|
||||
// class, we specialize the base class' nested template
|
||||
template<>
|
||||
struct storage_impl<true>
|
||||
{
|
||||
typedef Value type;
|
||||
};
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
// Function template argument deduction does many of the same things
|
||||
// as type matching during partial specialization, so we call a
|
||||
// function template to "store" T into the type memory addressed by
|
||||
// void(*)(T).
|
||||
template <class T>
|
||||
msvc_store_type<T,void(*)(T)>
|
||||
msvc_store_argument_type(void(*)(T));
|
||||
|
||||
template <class FunctionPointer>
|
||||
struct unaryfunptr_arg_type
|
||||
{
|
||||
// We don't want the function to be evaluated, just instantiated,
|
||||
// so protect it inside of sizeof.
|
||||
enum { dummy = sizeof(msvc_store_argument_type((FunctionPointer)0)) };
|
||||
|
||||
// Now pull the type out of the instantiated base class
|
||||
typedef typename msvc_type_memory<FunctionPointer>::storage::type type;
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
template <>
|
||||
struct unaryfunptr_arg_type<void(*)(void)>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
#endif // BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
|
||||
115
include/boost/parameter/aux_/preprocessor/flatten.hpp
Executable file
115
include/boost/parameter/aux_/preprocessor/flatten.hpp
Executable file
@@ -0,0 +1,115 @@
|
||||
// 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
|
||||
|
||||
103
include/boost/parameter/aux_/preprocessor/for_each.hpp
Executable file
103
include/boost/parameter/aux_/preprocessor/for_each.hpp
Executable file
@@ -0,0 +1,103 @@
|
||||
// Copyright Daniel Wallin 2005. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_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
|
||||
|
||||
131
include/boost/parameter/aux_/python/invoker.hpp
Executable file
131
include/boost/parameter/aux_/python/invoker.hpp
Executable file
@@ -0,0 +1,131 @@
|
||||
// Copyright Daniel Wallin 2005. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_INVOKER_051210_HPP
|
||||
# define BOOST_PARAMETER_INVOKER_051210_HPP
|
||||
|
||||
# include <boost/mpl/begin.hpp>
|
||||
# include <boost/mpl/next.hpp>
|
||||
# include <boost/mpl/deref.hpp>
|
||||
# include <boost/parameter/keyword.hpp>
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace python { namespace aux {
|
||||
|
||||
template <long Arity, class M, class R, class Args>
|
||||
struct invoker;
|
||||
|
||||
template <class M, class R>
|
||||
struct make_invoker
|
||||
{
|
||||
template <class Args>
|
||||
struct apply
|
||||
{
|
||||
typedef invoker<
|
||||
mpl::size<Args>::value, M, R, Args
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <long Arity, class 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;
|
||||
|
||||
template <class T, class R>
|
||||
struct make_call_invoker
|
||||
{
|
||||
template <class Args>
|
||||
struct apply
|
||||
{
|
||||
typedef call_invoker<
|
||||
mpl::size<Args>::value, T, R, Args
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <long Arity, class T, class Args>
|
||||
struct init_invoker;
|
||||
|
||||
template <class T>
|
||||
struct make_init_invoker
|
||||
{
|
||||
template <class Args>
|
||||
struct apply
|
||||
{
|
||||
typedef init_invoker<
|
||||
mpl::size<Args>::value, T, Args
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class M, class R, class Args>
|
||||
struct invoker<0, M, R, Args>
|
||||
{
|
||||
static R execute()
|
||||
{
|
||||
return M()(boost::type<R>());
|
||||
}
|
||||
};
|
||||
|
||||
template <class 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>
|
||||
{
|
||||
static R execute(T& self)
|
||||
{
|
||||
return self();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Args>
|
||||
struct init_invoker<0, T, Args>
|
||||
{
|
||||
static T* execute(T& self)
|
||||
{
|
||||
return new T;
|
||||
}
|
||||
};
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
|
||||
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/aux_/python/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))
|
||||
# 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))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
}}}} // namespace boost::parameter::python::aux
|
||||
|
||||
#endif // BOOST_PARAMETER_INVOKER_051210_HPP
|
||||
|
||||
93
include/boost/parameter/aux_/python/invoker_iterate.hpp
Executable file
93
include/boost/parameter/aux_/python/invoker_iterate.hpp
Executable file
@@ -0,0 +1,93 @@
|
||||
// Copyright Daniel Wallin 2005. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/dec.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
#define BOOST_PARAMETER_PY_ARG_TYPES(z, n, _) \
|
||||
typedef typename mpl::next< \
|
||||
BOOST_PP_CAT(iter,BOOST_PP_DEC(n)) \
|
||||
>::type BOOST_PP_CAT(iter,n); \
|
||||
\
|
||||
typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type BOOST_PP_CAT(spec,n); \
|
||||
typedef typename mpl::if_< \
|
||||
mpl::and_< \
|
||||
mpl::not_<typename BOOST_PP_CAT(spec,n)::required> \
|
||||
, typename BOOST_PP_CAT(spec,n)::optimized_default \
|
||||
> \
|
||||
, parameter::aux::maybe<typename BOOST_PP_CAT(spec,n)::type> \
|
||||
, typename BOOST_PP_CAT(spec,n)::type \
|
||||
>::type BOOST_PP_CAT(arg,n); \
|
||||
typedef typename BOOST_PP_CAT(spec,n)::keyword BOOST_PP_CAT(kw,n);
|
||||
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 1
|
||||
template <class M, class R, class Args>
|
||||
struct invoker<N, M, R, Args>
|
||||
#elif BOOST_PP_ITERATION_FLAGS() == 2
|
||||
template <class T, class R, class Args>
|
||||
struct call_invoker<N, T, R, Args>
|
||||
#elif BOOST_PP_ITERATION_FLAGS() == 3
|
||||
template <class T, class Args>
|
||||
struct init_invoker<N, T, Args>
|
||||
#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;
|
||||
typedef typename mpl::deref<iter0>::type spec0;
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
mpl::not_<typename spec0::required>
|
||||
, typename spec0::optimized_default
|
||||
>
|
||||
, parameter::aux::maybe<typename spec0::type>
|
||||
, typename spec0::type
|
||||
>::type arg0;
|
||||
typedef typename spec0::keyword kw0;
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, N, BOOST_PARAMETER_PY_ARG_TYPES, ~)
|
||||
|
||||
static
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 3
|
||||
T*
|
||||
#else
|
||||
R
|
||||
#endif
|
||||
execute(
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 2 || BOOST_PP_ITERATION_FLAGS() == 4
|
||||
T& self
|
||||
,
|
||||
#endif
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, arg, a)
|
||||
)
|
||||
{
|
||||
return
|
||||
#if BOOST_PP_ITERATION_FLAGS() == 1 || BOOST_PP_ITERATION_FLAGS() == 4
|
||||
M()(
|
||||
boost::type<R>()
|
||||
# if BOOST_PP_ITERATION_FLAGS() == 4
|
||||
, self
|
||||
# endif
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
|
||||
);
|
||||
#elif BOOST_PP_ITERATION_FLAGS() == 2
|
||||
self(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
|
||||
);
|
||||
#elif BOOST_PP_ITERATION_FLAGS() == 3
|
||||
new T(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, parameter::keyword<kw, >::get() = a)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#undef BOOST_PARAMETER_PY_ARG_TYPES
|
||||
#undef N
|
||||
|
||||
65
include/boost/parameter/aux_/set.hpp
Executable file
65
include/boost/parameter/aux_/set.hpp
Executable file
@@ -0,0 +1,65 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_SET_060912_HPP
|
||||
# define BOOST_PARAMETER_SET_060912_HPP
|
||||
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
|
||||
&& !BOOST_WORKAROUND(__GNUC__, < 3)
|
||||
# include <boost/mpl/insert.hpp>
|
||||
# include <boost/mpl/set/set0.hpp>
|
||||
# include <boost/mpl/has_key.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
typedef mpl::set0<> set0;
|
||||
|
||||
template <class Set, class K>
|
||||
struct insert_
|
||||
{
|
||||
typedef typename mpl::insert<Set, K>::type type;
|
||||
};
|
||||
|
||||
template <class Set, class K>
|
||||
struct has_key_
|
||||
{
|
||||
typedef typename mpl::has_key<Set, K>::type type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
# else
|
||||
|
||||
# include <boost/mpl/list.hpp>
|
||||
# include <boost/mpl/end.hpp>
|
||||
# include <boost/mpl/find.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/mpl/push_front.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
typedef mpl::list0<> set0;
|
||||
|
||||
template <class Set, class K>
|
||||
struct insert_
|
||||
{
|
||||
typedef typename mpl::push_front<Set, K>::type type;
|
||||
};
|
||||
|
||||
template <class Set, class K>
|
||||
struct has_key_
|
||||
{
|
||||
typedef typename mpl::find<Set, K>::type iter;
|
||||
typedef mpl::not_<
|
||||
is_same<iter, typename mpl::end<Set>::type>
|
||||
> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
#endif // BOOST_PARAMETER_SET_060912_HPP
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
# define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
|
||||
|
||||
# include <boost/parameter/aux_/unwrap_cv_reference.hpp>
|
||||
# include <boost/parameter/aux_/tagged_argument.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
template <class Keyword, class Arg>
|
||||
struct tagged_argument;
|
||||
|
||||
template <class Keyword, class ActualArg
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
, class = typename is_cv_reference_wrapper<ActualArg>::type
|
||||
|
||||
@@ -3,19 +3,31 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAGGED_ARGUMENT_050328_HPP
|
||||
#define TAGGED_ARGUMENT_050328_HPP
|
||||
#ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
|
||||
# define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
|
||||
|
||||
#include <boost/parameter/aux_/void.hpp>
|
||||
#include <boost/parameter/aux_/arg_list.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_reference.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
|
||||
struct tagged_argument : tagged_argument_base
|
||||
{
|
||||
typedef Keyword key_type;
|
||||
typedef Arg value_type;
|
||||
@@ -23,6 +35,22 @@ struct tagged_argument
|
||||
|
||||
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>
|
||||
@@ -40,15 +68,120 @@ struct tagged_argument
|
||||
, 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))
|
||||
// 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
|
||||
};
|
||||
|
||||
// Defines a metafunction, is_tagged_argument, that identifies
|
||||
// tagged_argument specializations.
|
||||
BOOST_PYTHON_IS_XXX_DEF(tagged_argument,tagged_argument,2)
|
||||
// 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>
|
||||
>
|
||||
{};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
#endif // TAGGED_ARGUMENT_050328_HPP
|
||||
#endif // BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
|
||||
|
||||
|
||||
47
include/boost/parameter/aux_/template_keyword.hpp
Executable file
47
include/boost/parameter/aux_/template_keyword.hpp
Executable file
@@ -0,0 +1,47 @@
|
||||
// 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
|
||||
|
||||
@@ -3,16 +3,27 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef VOID_050329_HPP
|
||||
#define VOID_050329_HPP
|
||||
#ifndef BOOST_PARAMETER_VOID_050329_HPP
|
||||
#define BOOST_PARAMETER_VOID_050329_HPP
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
namespace boost { namespace parameter {
|
||||
|
||||
// A placemarker for "no argument passed."
|
||||
// MAINTAINER NOTE: Do not make this into a metafunction
|
||||
struct void_ {};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
namespace aux
|
||||
{
|
||||
|
||||
#endif // VOID_050329_HPP
|
||||
inline void_& void_reference()
|
||||
{
|
||||
static void_ instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
}} // namespace boost::parameter
|
||||
|
||||
#endif // BOOST_PARAMETER_VOID_050329_HPP
|
||||
|
||||
|
||||
@@ -5,35 +5,83 @@
|
||||
# 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/parameter/aux_/void.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
# include <boost/parameter/aux_/void.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# endif
|
||||
# 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 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
|
||||
template <class Parameters, class Keyword, class Default = aux::void_>
|
||||
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_>
|
||||
struct binding
|
||||
{
|
||||
typedef typename mpl::apply_wrap2<
|
||||
typename Parameters::binding,Keyword,
|
||||
typename mpl::if_<is_same<Default,aux::void_>,void,Default>::type
|
||||
typedef typename mpl::eval_if<
|
||||
is_same<Parameters, int>
|
||||
, mpl::identity<int>
|
||||
, binding_eti<Parameters, Keyword, Default>
|
||||
>::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
|
||||
};
|
||||
# endif
|
||||
|
||||
@@ -44,10 +92,11 @@ struct binding
|
||||
template <class Parameters, class Keyword, class DefaultFn>
|
||||
struct lazy_binding
|
||||
{
|
||||
typedef typename mpl::apply_wrap2<
|
||||
typedef typename mpl::apply_wrap3<
|
||||
typename Parameters::binding
|
||||
, Keyword
|
||||
, typename aux::result_of0<DefaultFn>::type
|
||||
, mpl::true_
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
|
||||
#include <boost/parameter/aux_/tag.hpp>
|
||||
#include <boost/parameter/aux_/default.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace boost { namespace parameter {
|
||||
|
||||
@@ -29,10 +28,10 @@ namespace boost { namespace parameter {
|
||||
// f(rate = 1, skew = 2.4);
|
||||
//
|
||||
template <class Tag>
|
||||
struct keyword : noncopyable
|
||||
struct keyword
|
||||
{
|
||||
template <class T>
|
||||
typename aux::tag<Tag, T>::type
|
||||
typename aux::tag<Tag, T>::type const
|
||||
operator=(T& x) const
|
||||
{
|
||||
typedef typename aux::tag<Tag, T>::type result;
|
||||
@@ -55,7 +54,7 @@ struct keyword : noncopyable
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
|
||||
template <class T>
|
||||
typename aux::tag<Tag, T const>::type
|
||||
typename aux::tag<Tag, T const>::type const
|
||||
operator=(T const& x) const
|
||||
{
|
||||
typedef typename aux::tag<Tag, T const>::type result;
|
||||
@@ -92,26 +91,60 @@ struct keyword : noncopyable
|
||||
// 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()
|
||||
{
|
||||
static keyword<Tag> result;
|
||||
return result;
|
||||
return const_cast<keyword<Tag>&>(instance);
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
|
||||
namespace tag_namespace { struct name; } \
|
||||
::boost::parameter::keyword<tag_namespace::name>& name \
|
||||
= ::boost::parameter::keyword<tag_namespace::name>::get();
|
||||
// name in namespace tag_namespace, and declares and initializes a
|
||||
// reference in an anonymous namespace to a singleton instance of that
|
||||
// type.
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
|
||||
namespace tag_namespace \
|
||||
{ \
|
||||
struct name \
|
||||
{ \
|
||||
static char const* keyword_name() \
|
||||
{ \
|
||||
return #name; \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
static ::boost::parameter::keyword<tag_namespace::name> const& name \
|
||||
= ::boost::parameter::keyword<tag_namespace::name>::instance;
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
|
||||
namespace tag_namespace \
|
||||
{ \
|
||||
struct name \
|
||||
{ \
|
||||
static char const* keyword_name() \
|
||||
{ \
|
||||
return #name; \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
namespace \
|
||||
{ \
|
||||
::boost::parameter::keyword<tag_namespace::name> const& name \
|
||||
= ::boost::parameter::keyword<tag_namespace::name>::instance;\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespace boost::parameter
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
#define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters) \
|
||||
\
|
||||
template<class Params> \
|
||||
ret BOOST_PP_CAT(name, _with_named_params)(Params const&); \
|
||||
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p); \
|
||||
\
|
||||
BOOST_PP_REPEAT_FROM_TO( \
|
||||
lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
BOOST_PARAMETER_MAX_ARITY \
|
||||
, BOOST_PP_SEQ_SIZE(ArgTypes) \
|
||||
) \
|
||||
, ::boost::parameter::aux::void_ BOOST_PP_INTERCEPT \
|
||||
, ::boost::parameter::void_ BOOST_PP_INTERCEPT \
|
||||
)
|
||||
|
||||
# else
|
||||
|
||||
155
include/boost/parameter/name.hpp
Executable file
155
include/boost/parameter/name.hpp
Executable file
@@ -0,0 +1,155 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_NAME_060806_HPP
|
||||
# define BOOST_PARAMETER_NAME_060806_HPP
|
||||
|
||||
# include <boost/parameter/keyword.hpp>
|
||||
# include <boost/parameter/value_type.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/stringize.hpp>
|
||||
# include <boost/preprocessor/control/iif.hpp>
|
||||
# include <boost/preprocessor/tuple/eat.hpp>
|
||||
# include <boost/preprocessor/tuple/elem.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
|
||||
# if !defined(BOOST_NO_SFINAE) \
|
||||
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
# include <boost/utility/enable_if.hpp>
|
||||
# include <boost/mpl/lambda.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace aux {
|
||||
|
||||
// Tag type passed to MPL lambda.
|
||||
struct lambda_tag;
|
||||
|
||||
struct name_tag_base
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct name_tag
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_name_tag
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template <class T>
|
||||
struct lambda<
|
||||
T
|
||||
, typename enable_if<
|
||||
parameter::aux::is_name_tag<T>, parameter::aux::lambda_tag
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef true_ is_le;
|
||||
typedef bind3< quote3<parameter::value_type>, arg<2>, T, void> result_;
|
||||
typedef result_ type;
|
||||
};
|
||||
|
||||
}} // namespace boost::mpl
|
||||
|
||||
# endif
|
||||
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# include <boost/preprocessor/detail/split.hpp>
|
||||
// From Paul Mensonides
|
||||
# define BOOST_PARAMETER_IS_BINARY(x) \
|
||||
BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_BINARY_C x BOOST_PP_COMMA() 0) \
|
||||
/**/
|
||||
# define BOOST_PARAMETER_IS_BINARY_C(x,y) \
|
||||
~, 1 BOOST_PP_RPAREN() \
|
||||
BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \
|
||||
/**/
|
||||
# else
|
||||
# include <boost/preprocessor/detail/is_binary.hpp>
|
||||
# define BOOST_PARAMETER_IS_BINARY(x) BOOST_PP_IS_BINARY(x)
|
||||
# endif
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
# define BOOST_PARAMETER_NAME_OBJECT(tag, name) \
|
||||
static ::boost::parameter::keyword<tag> 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1169
include/boost/parameter/preprocessor.hpp
Executable file
1169
include/boost/parameter/preprocessor.hpp
Executable file
File diff suppressed because it is too large
Load Diff
735
include/boost/parameter/python.hpp
Executable file
735
include/boost/parameter/python.hpp
Executable file
@@ -0,0 +1,735 @@
|
||||
// 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_PYTHON_060209_HPP
|
||||
# define BOOST_PARAMETER_PYTHON_060209_HPP
|
||||
|
||||
# include <boost/mpl/vector.hpp>
|
||||
# include <boost/mpl/fold.hpp>
|
||||
# include <boost/mpl/prior.hpp>
|
||||
# include <boost/mpl/shift_right.hpp>
|
||||
# include <boost/mpl/shift_left.hpp>
|
||||
# include <boost/mpl/bitand.hpp>
|
||||
# include <boost/mpl/pair.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/mpl/push_back.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/count_if.hpp>
|
||||
# include <boost/mpl/transform.hpp>
|
||||
# include <boost/mpl/front.hpp>
|
||||
# include <boost/mpl/iterator_range.hpp>
|
||||
# include <boost/mpl/next.hpp>
|
||||
# include <boost/mpl/begin_end.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/mpl/empty.hpp>
|
||||
# include <boost/python/def.hpp>
|
||||
# include <boost/python/make_constructor.hpp>
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/to_python_converter.hpp>
|
||||
# include <boost/parameter/aux_/maybe.hpp>
|
||||
# include <boost/parameter/aux_/python/invoker.hpp>
|
||||
|
||||
namespace boost { namespace parameter { namespace python
|
||||
{
|
||||
namespace python_ = boost::python;
|
||||
}}}
|
||||
|
||||
namespace boost { namespace parameter { namespace python { namespace aux
|
||||
{
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
if (unspecified.ob_type == 0)
|
||||
{
|
||||
unspecified.ob_type = &PyType_Type;
|
||||
PyType_Ready(&unspecified);
|
||||
}
|
||||
|
||||
return (PyObject*)&unspecified;
|
||||
}
|
||||
|
||||
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 { namespace python
|
||||
{
|
||||
|
||||
// Converts a Python value to a maybe<T>
|
||||
template <class T>
|
||||
struct arg_from_python<parameter::aux::maybe<T> >
|
||||
: arg_from_python<T>
|
||||
{
|
||||
arg_from_python(PyObject* p)
|
||||
: arg_from_python<T>(p)
|
||||
, empty(parameter::python::aux::unspecified_type() == p)
|
||||
{}
|
||||
|
||||
bool convertible() const
|
||||
{
|
||||
return empty || arg_from_python<T>::convertible();
|
||||
}
|
||||
|
||||
parameter::aux::maybe<T> operator()()
|
||||
{
|
||||
if (empty)
|
||||
{
|
||||
return parameter::aux::maybe<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return parameter::aux::maybe<T>(
|
||||
arg_from_python<T>::operator()()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool empty;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
namespace boost { namespace parameter { namespace python {
|
||||
|
||||
namespace aux
|
||||
{
|
||||
|
||||
template <class K>
|
||||
struct is_optional
|
||||
: mpl::not_<
|
||||
mpl::or_<typename K::required, typename K::optimized_default>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class K, class Required, class Optimized, class T>
|
||||
struct arg_spec
|
||||
{
|
||||
typedef K keyword;
|
||||
typedef Required required;
|
||||
typedef T type;
|
||||
typedef Optimized optimized_default;
|
||||
};
|
||||
|
||||
template <class K, class T, class Optimized = mpl::false_>
|
||||
struct make_arg_spec_impl
|
||||
{
|
||||
typedef arg_spec<
|
||||
typename K::first, typename K::second, Optimized, T
|
||||
> type;
|
||||
};
|
||||
|
||||
template <class K, class T>
|
||||
struct make_arg_spec_impl<K, T, typename K::third>
|
||||
{
|
||||
typedef arg_spec<
|
||||
typename K::first, typename K::second, typename K::third, T
|
||||
> type;
|
||||
};
|
||||
|
||||
template <class K, class T>
|
||||
struct make_arg_spec
|
||||
: make_arg_spec_impl<K, T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Spec, class State>
|
||||
struct combinations_op
|
||||
{
|
||||
typedef typename State::second bits;
|
||||
typedef typename State::first result0;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_<
|
||||
typename Spec::required
|
||||
, typename Spec::optimized_default
|
||||
, mpl::bitand_<bits, mpl::long_<1> >
|
||||
>
|
||||
, typename mpl::push_back<result0, Spec>::type
|
||||
, result0
|
||||
>::type result;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_<
|
||||
typename Spec::required
|
||||
, typename Spec::optimized_default
|
||||
>
|
||||
, bits
|
||||
, typename mpl::shift_right<bits, mpl::long_<1> >::type
|
||||
>::type next_bits;
|
||||
|
||||
typedef mpl::pair<
|
||||
result
|
||||
, next_bits
|
||||
> type;
|
||||
};
|
||||
|
||||
// Used as start value in the recursive arg() composition below.
|
||||
struct no_keywords
|
||||
{
|
||||
template <class T>
|
||||
T const& operator,(T const& x) const
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Def, class F, class Iter, class End, class Keywords>
|
||||
void def_combination_aux0(
|
||||
Def def, F f, Iter, End, Keywords const& keywords, mpl::false_)
|
||||
{
|
||||
typedef typename mpl::deref<Iter>::type spec;
|
||||
typedef typename spec::keyword kw;
|
||||
|
||||
def_combination_aux(
|
||||
def, f, typename mpl::next<Iter>::type(), End()
|
||||
, (
|
||||
keywords, boost::python::arg(kw::keyword_name())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class Def, class F, class Iter, class End, class Keywords>
|
||||
void def_combination_aux0(
|
||||
Def def, F f, Iter, End, Keywords const& keywords, mpl::true_)
|
||||
{
|
||||
typedef typename mpl::deref<Iter>::type spec;
|
||||
typedef typename spec::keyword kw;
|
||||
|
||||
def_combination_aux(
|
||||
def, f, typename mpl::next<Iter>::type(), End()
|
||||
, (
|
||||
keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inline void initialize_converter()
|
||||
{
|
||||
static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
|
||||
}
|
||||
|
||||
template <class Def, class F, class Iter, class End, class Keywords>
|
||||
void def_combination_aux(
|
||||
Def def, F f, Iter, End, Keywords const& keywords)
|
||||
{
|
||||
typedef typename mpl::deref<Iter>::type spec;
|
||||
|
||||
typedef typename mpl::and_<
|
||||
typename spec::optimized_default
|
||||
, mpl::not_<typename spec::required>
|
||||
>::type optimized_default;
|
||||
|
||||
def_combination_aux0(
|
||||
def, f, Iter(), End(), keywords, optimized_default()
|
||||
);
|
||||
}
|
||||
|
||||
template <class Def, class F, class End, class Keywords>
|
||||
void def_combination_aux(
|
||||
Def def, F f, End, End, Keywords const& keywords)
|
||||
{
|
||||
def(f, keywords);
|
||||
}
|
||||
|
||||
template <class Def, class F, class End>
|
||||
void def_combination_aux(
|
||||
Def def, F f, End, End, no_keywords const&)
|
||||
{
|
||||
def(f);
|
||||
}
|
||||
|
||||
template <
|
||||
class Def, class Specs, class Bits, class Invoker
|
||||
>
|
||||
void def_combination(
|
||||
Def def, Specs*, Bits, Invoker*)
|
||||
{
|
||||
typedef typename mpl::fold<
|
||||
Specs
|
||||
, mpl::pair<mpl::vector0<>, Bits>
|
||||
, combinations_op<mpl::_2, mpl::_1>
|
||||
>::type combination0;
|
||||
|
||||
typedef typename combination0::first combination;
|
||||
|
||||
typedef typename mpl::apply_wrap1<
|
||||
Invoker, combination
|
||||
>::type invoker;
|
||||
|
||||
def_combination_aux(
|
||||
def
|
||||
, &invoker::execute
|
||||
, typename mpl::begin<combination>::type()
|
||||
, typename mpl::end<combination>::type()
|
||||
, no_keywords()
|
||||
);
|
||||
}
|
||||
|
||||
template <
|
||||
class Def, class Specs, class Bits, class End, class Invoker
|
||||
>
|
||||
void def_combinations(
|
||||
Def def, Specs*, Bits, End, Invoker*)
|
||||
{
|
||||
initialize_converter();
|
||||
|
||||
def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
|
||||
|
||||
def_combinations(
|
||||
def
|
||||
, (Specs*)0
|
||||
, mpl::long_<Bits::value + 1>()
|
||||
, End()
|
||||
, (Invoker*)0
|
||||
);
|
||||
}
|
||||
|
||||
template <
|
||||
class Def, class Specs, class End, class Invoker
|
||||
>
|
||||
void def_combinations(
|
||||
Def, Specs*, End, End, Invoker*)
|
||||
{}
|
||||
|
||||
struct not_specified {};
|
||||
|
||||
template <class CallPolicies>
|
||||
struct call_policies_as_options
|
||||
{
|
||||
call_policies_as_options(CallPolicies const& call_policies)
|
||||
: call_policies(call_policies)
|
||||
{}
|
||||
|
||||
CallPolicies const& policies() const
|
||||
{
|
||||
return call_policies;
|
||||
}
|
||||
|
||||
char const* doc() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CallPolicies call_policies;
|
||||
};
|
||||
|
||||
template <class Class, class Options = not_specified>
|
||||
struct def_class
|
||||
{
|
||||
def_class(Class& cl, char const* name, Options options = Options())
|
||||
: cl(cl)
|
||||
, name(name)
|
||||
, options(options)
|
||||
{}
|
||||
|
||||
template <class F>
|
||||
void def(F f, not_specified const*) 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
|
||||
{
|
||||
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>
|
||||
struct def_init
|
||||
{
|
||||
def_init(Class& cl, CallPolicies call_policies = CallPolicies())
|
||||
: cl(cl)
|
||||
, call_policies(call_policies)
|
||||
{}
|
||||
|
||||
template <class F>
|
||||
void operator()(F f) const
|
||||
{
|
||||
cl.def(
|
||||
"__init__"
|
||||
, boost::python::make_constructor(f, call_policies)
|
||||
);
|
||||
}
|
||||
|
||||
template <class F, class Keywords>
|
||||
void operator()(F f, Keywords const& keywords) const
|
||||
{
|
||||
cl.def(
|
||||
"__init__"
|
||||
, boost::python::make_constructor(f, call_policies, keywords)
|
||||
);
|
||||
}
|
||||
|
||||
Class& cl;
|
||||
CallPolicies call_policies;
|
||||
};
|
||||
|
||||
struct def_function
|
||||
{
|
||||
def_function(char const* name)
|
||||
: name(name)
|
||||
{}
|
||||
|
||||
template <class F>
|
||||
void operator()(F f) const
|
||||
{
|
||||
boost::python::def(name, f);
|
||||
}
|
||||
|
||||
template <class F, class Keywords>
|
||||
void operator()(F f, Keywords const& keywords) const
|
||||
{
|
||||
boost::python::def(name, f, keywords);
|
||||
}
|
||||
|
||||
char const* name;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
template <class M, class Signature>
|
||||
void def(char const* name, Signature)
|
||||
{
|
||||
typedef mpl::iterator_range<
|
||||
typename mpl::next<
|
||||
typename mpl::begin<Signature>::type
|
||||
>::type
|
||||
, typename mpl::end<Signature>::type
|
||||
> arg_types;
|
||||
|
||||
typedef typename mpl::transform<
|
||||
typename M::keywords
|
||||
, arg_types
|
||||
, aux::make_arg_spec<mpl::_1, mpl::_2>
|
||||
, mpl::back_inserter<mpl::vector0<> >
|
||||
>::type arg_specs;
|
||||
|
||||
typedef typename mpl::count_if<
|
||||
arg_specs
|
||||
, aux::is_optional<mpl::_1>
|
||||
>::type optional_arity;
|
||||
|
||||
typedef typename mpl::front<Signature>::type result_type;
|
||||
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
||||
|
||||
aux::def_combinations(
|
||||
aux::def_function(name)
|
||||
, (arg_specs*)0
|
||||
, mpl::long_<0>()
|
||||
, mpl::long_<upper::value>()
|
||||
, (aux::make_invoker<M, result_type>*)0
|
||||
);
|
||||
}
|
||||
|
||||
template <class M, class Class, class Signature>
|
||||
void def(Class& cl, char const* name, Signature)
|
||||
{
|
||||
typedef mpl::iterator_range<
|
||||
typename mpl::next<
|
||||
typename mpl::begin<Signature>::type
|
||||
>::type
|
||||
, typename mpl::end<Signature>::type
|
||||
> arg_types;
|
||||
|
||||
typedef typename mpl::transform<
|
||||
typename M::keywords
|
||||
, arg_types
|
||||
, aux::make_arg_spec<mpl::_1, mpl::_2>
|
||||
, mpl::back_inserter<mpl::vector0<> >
|
||||
>::type arg_specs;
|
||||
|
||||
typedef typename mpl::count_if<
|
||||
arg_specs
|
||||
, aux::is_optional<mpl::_1>
|
||||
>::type optional_arity;
|
||||
|
||||
typedef typename mpl::front<Signature>::type result_type;
|
||||
typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
||||
|
||||
aux::def_combinations(
|
||||
aux::def_class<Class>(cl, name)
|
||||
, (arg_specs*)0
|
||||
, mpl::long_<0>()
|
||||
, mpl::long_<upper::value>()
|
||||
, (aux::make_invoker<M, result_type>*)0
|
||||
);
|
||||
}
|
||||
|
||||
namespace aux
|
||||
{
|
||||
|
||||
template <class K>
|
||||
struct keyword
|
||||
{
|
||||
typedef K type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct keyword<K*>
|
||||
{
|
||||
typedef K type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct keyword<K**>
|
||||
{
|
||||
typedef K type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct required
|
||||
{
|
||||
typedef mpl::true_ type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct required<K*>
|
||||
{
|
||||
typedef mpl::false_ type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct optimized
|
||||
{
|
||||
typedef mpl::true_ type;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
struct optimized<K**>
|
||||
{
|
||||
typedef mpl::false_ type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct make_kw_spec;
|
||||
|
||||
template <class K, class T>
|
||||
struct make_kw_spec<K(T)>
|
||||
{
|
||||
typedef arg_spec<
|
||||
typename keyword<K>::type
|
||||
, typename required<K>::type
|
||||
, typename optimized<K>::type
|
||||
, T
|
||||
> type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
|
||||
struct init
|
||||
: boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
|
||||
{
|
||||
init(CallPolicies call_policies = CallPolicies())
|
||||
: call_policies(call_policies)
|
||||
{}
|
||||
|
||||
template <class CallPolicies1>
|
||||
init<ParameterSpecs, CallPolicies1>
|
||||
operator[](CallPolicies1 const& call_policies) const
|
||||
{
|
||||
return init<ParameterSpecs, CallPolicies1>(call_policies);
|
||||
}
|
||||
|
||||
template <class Class>
|
||||
void visit_aux(Class& cl, mpl::true_) const
|
||||
{
|
||||
cl.def(boost::python::init<>()[call_policies]);
|
||||
}
|
||||
|
||||
template <class Class>
|
||||
void visit_aux(Class& cl, mpl::false_) const
|
||||
{
|
||||
typedef typename mpl::transform<
|
||||
ParameterSpecs
|
||||
, aux::make_kw_spec<mpl::_>
|
||||
, mpl::back_inserter<mpl::vector0<> >
|
||||
>::type arg_specs;
|
||||
|
||||
typedef typename mpl::count_if<
|
||||
arg_specs
|
||||
, aux::is_optional<mpl::_>
|
||||
>::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)
|
||||
, (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>
|
||||
struct call
|
||||
: boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
|
||||
{
|
||||
call(CallPolicies const& call_policies = CallPolicies())
|
||||
: call_policies(call_policies)
|
||||
{}
|
||||
|
||||
template <class CallPolicies1>
|
||||
call<ParameterSpecs, CallPolicies1>
|
||||
operator[](CallPolicies1 const& call_policies) const
|
||||
{
|
||||
return call<ParameterSpecs, CallPolicies1>(call_policies);
|
||||
}
|
||||
|
||||
template <class Class>
|
||||
void visit(Class& cl) const
|
||||
{
|
||||
typedef mpl::iterator_range<
|
||||
typename mpl::next<
|
||||
typename mpl::begin<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;
|
||||
|
||||
typedef aux::call_policies_as_options<CallPolicies> options;
|
||||
|
||||
aux::def_combinations(
|
||||
aux::def_class<Class, options>(cl, "__call__", options(call_policies))
|
||||
, (arg_specs*)0
|
||||
, mpl::long_<0>()
|
||||
, mpl::long_<upper::value>()
|
||||
, (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
|
||||
);
|
||||
}
|
||||
|
||||
CallPolicies call_policies;
|
||||
};
|
||||
|
||||
template <class Fwd, class 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
|
||||
|
||||
108
include/boost/parameter/value_type.hpp
Executable file
108
include/boost/parameter/value_type.hpp
Executable file
@@ -0,0 +1,108 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_VALUE_TYPE_060921_HPP
|
||||
# define BOOST_PARAMETER_VALUE_TYPE_060921_HPP
|
||||
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/assert.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/parameter/aux_/result_of0.hpp>
|
||||
# include <boost/parameter/aux_/void.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace parameter {
|
||||
|
||||
// A metafunction that, given an argument pack, returns the type of
|
||||
// the parameter identified by the given keyword. If no such
|
||||
// parameter has been specified, returns Default
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
template <class Parameters, class Keyword, class Default>
|
||||
struct value_type0
|
||||
{
|
||||
typedef typename mpl::apply_wrap3<
|
||||
typename Parameters::binding,Keyword,Default,mpl::false_
|
||||
>::type type;
|
||||
|
||||
BOOST_MPL_ASSERT_NOT((
|
||||
mpl::and_<
|
||||
is_same<Default, void_>
|
||||
, is_same<type, void_>
|
||||
>
|
||||
));
|
||||
};
|
||||
# endif
|
||||
|
||||
template <class Parameters, class Keyword, class Default = void_>
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
struct value_type
|
||||
# else
|
||||
struct value_type_eti
|
||||
# endif
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
typedef typename mpl::eval_if<
|
||||
mpl::is_placeholder<Parameters>
|
||||
, mpl::identity<int>
|
||||
, value_type0<Parameters,Keyword,Default>
|
||||
>::type type;
|
||||
# else
|
||||
typedef typename mpl::apply_wrap3<
|
||||
typename Parameters::binding,Keyword,Default,mpl::false_
|
||||
>::type type;
|
||||
|
||||
BOOST_MPL_ASSERT_NOT((
|
||||
mpl::and_<
|
||||
is_same<Default, void_>
|
||||
, is_same<type, void_>
|
||||
>
|
||||
));
|
||||
# endif
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
|
||||
# endif
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
template <class Parameters, class Keyword, class Default = void_>
|
||||
struct value_type
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
is_same<Parameters, int>
|
||||
, mpl::identity<int>
|
||||
, value_type_eti<Parameters, Keyword, Default>
|
||||
>::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
|
||||
};
|
||||
# endif
|
||||
|
||||
// A metafunction that, given an argument pack, returns the type of
|
||||
// the parameter identified by the given keyword. If no such
|
||||
// parameter has been specified, returns the type returned by invoking
|
||||
// DefaultFn
|
||||
template <class Parameters, class Keyword, class DefaultFn>
|
||||
struct lazy_value_type
|
||||
{
|
||||
typedef typename mpl::apply_wrap3<
|
||||
typename Parameters::binding
|
||||
, Keyword
|
||||
, typename aux::result_of0<DefaultFn>::type
|
||||
, mpl::false_
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::parameter
|
||||
|
||||
#endif // BOOST_PARAMETER_VALUE_TYPE_060921_HPP
|
||||
|
||||
12
index.html
Executable file
12
index.html
Executable file
@@ -0,0 +1,12 @@
|
||||
<!-- 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>.
|
||||
</body>
|
||||
</html>
|
||||
36
test/Jamfile.v2
Normal file
36
test/Jamfile.v2
Normal file
@@ -0,0 +1,36 @@
|
||||
# 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
|
||||
;
|
||||
|
||||
test-suite "parameter"
|
||||
: [ run basics.cpp ]
|
||||
[ run sfinae.cpp ]
|
||||
[ run macros.cpp ]
|
||||
[ run earwicker.cpp ]
|
||||
[ run tutorial.cpp ]
|
||||
[ run singular.cpp ]
|
||||
[ run mpl.cpp ]
|
||||
[ run preprocessor.cpp ]
|
||||
[ run preprocessor_deduced.cpp ]
|
||||
[ run efficiency.cpp : : : : : <variant>release ]
|
||||
[ run maybe.cpp ]
|
||||
[ run deduced.cpp ]
|
||||
[ run optional_deduced_sfinae.cpp ]
|
||||
[ run deduced_dependent_predicate.cpp ]
|
||||
[ run normalized_argument_types.cpp ]
|
||||
[ compile ntp.cpp ]
|
||||
[ compile unwrap_cv_reference.cpp ]
|
||||
[ compile-fail duplicates.cpp ]
|
||||
[ compile-fail deduced_unmatched_arg.cpp ]
|
||||
[ compile compose.cpp ]
|
||||
[ bpl-test python_test ]
|
||||
;
|
||||
|
||||
112
test/basics.cpp
Executable file
112
test/basics.cpp
Executable file
@@ -0,0 +1,112 @@
|
||||
// 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 <cassert>
|
||||
#include <string.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include "basics.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
// A separate function for getting the "value" key, so we can deduce
|
||||
// F and use lazy_binding on it.
|
||||
template <class Params, class F>
|
||||
typename boost::parameter::lazy_binding<Params,tag::value,F>::type
|
||||
extract_value(Params const& p, F const& f)
|
||||
{
|
||||
typename boost::parameter::lazy_binding<
|
||||
Params, tag::value, F
|
||||
>::type v = p[value || f ];
|
||||
return v;
|
||||
}
|
||||
|
||||
template<class Params>
|
||||
int f_impl(Params const& p)
|
||||
{
|
||||
typename boost::parameter::binding<Params, tag::name>::type
|
||||
n = p[name];
|
||||
|
||||
typename boost::parameter::binding<
|
||||
Params, tag::value, double
|
||||
>::type v = extract_value(p, boost::bind(&value_default));
|
||||
|
||||
typename boost::parameter::binding<
|
||||
Params, tag::index, int
|
||||
>::type i =
|
||||
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
|
||||
p[test::index | 999];
|
||||
#else
|
||||
p[index | 999];
|
||||
#endif
|
||||
|
||||
p[tester](n,v,i);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<class Tester, class Name, class Value, class Index>
|
||||
int f(Tester const& t, const Name& name_,
|
||||
const Value& value_, const Index& index_)
|
||||
{
|
||||
return f_impl(f_parameters()(t, name_, value_, index_));
|
||||
}
|
||||
|
||||
template<class Tester, class Name, class Value>
|
||||
int f(Tester const& t, const Name& name_, const Value& value_)
|
||||
{
|
||||
return f_impl(f_parameters()(t, name_, value_));
|
||||
}
|
||||
|
||||
template<class Tester, class Name>
|
||||
int f(Tester const& t, const Name& name_)
|
||||
{
|
||||
return f_impl(f_parameters()(t, name_));
|
||||
}
|
||||
|
||||
template<class Params>
|
||||
int f_list(Params const& params)
|
||||
{
|
||||
return f_impl(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using test::f;
|
||||
using test::f_list;
|
||||
using test::name;
|
||||
using test::value;
|
||||
using test::index;
|
||||
using test::tester;
|
||||
|
||||
f(
|
||||
test::values(S("foo"), S("bar"), S("baz"))
|
||||
, S("foo"), S("bar"), S("baz")
|
||||
);
|
||||
|
||||
int x = 56;
|
||||
f(
|
||||
test::values("foo", 666.222, 56)
|
||||
, index = boost::ref(x), name = "foo"
|
||||
);
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// No comma operator available on Borland
|
||||
f_list((
|
||||
tester = test::values("foo", 666.222, 56)
|
||||
, index = boost::ref(x)
|
||||
, name = "foo"
|
||||
));
|
||||
#endif
|
||||
|
||||
//f(index = 56, name = 55); // won't compile
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
112
test/basics.hpp
Executable file
112
test/basics.hpp
Executable file
@@ -0,0 +1,112 @@
|
||||
// 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)
|
||||
|
||||
#ifndef BASICS_050424_HPP
|
||||
#define BASICS_050424_HPP
|
||||
|
||||
#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 {
|
||||
|
||||
BOOST_PARAMETER_KEYWORD(tag, name)
|
||||
BOOST_PARAMETER_KEYWORD(tag, value)
|
||||
BOOST_PARAMETER_KEYWORD(tag, index)
|
||||
BOOST_PARAMETER_KEYWORD(tag, tester)
|
||||
|
||||
using namespace boost::parameter;
|
||||
|
||||
struct f_parameters // vc6 is happier with inheritance than with a typedef
|
||||
: parameters<
|
||||
tag::tester
|
||||
, tag::name
|
||||
, tag::value
|
||||
, tag::index
|
||||
>
|
||||
{};
|
||||
|
||||
inline double value_default()
|
||||
{
|
||||
return 666.222;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool equal(T const& x, T const& y)
|
||||
{
|
||||
return x == 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
|
||||
|
||||
template <class Name, class Value, class Index>
|
||||
struct values_t
|
||||
{
|
||||
values_t(Name const& n, Value const& v, Index const& i)
|
||||
: n(n), v(v), i(i)
|
||||
{}
|
||||
|
||||
template <class Name_, class Value_, class Index_>
|
||||
void operator()(Name_ const& n_, Value_ const& v_, Index_ const& i_) const
|
||||
{
|
||||
|
||||
// Only VC and its emulators fail this; they seem to have
|
||||
// problems with deducing the constness of string literal
|
||||
// arrays.
|
||||
#if defined(_MSC_VER) \
|
||||
&& (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) \
|
||||
|| BOOST_WORKAROUND(BOOST_MSVC, < 1310)) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# else
|
||||
BOOST_MPL_ASSERT((boost::is_same<Index,Index_>));
|
||||
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_));
|
||||
}
|
||||
|
||||
Name const& n;
|
||||
Value const& v;
|
||||
Index const& i;
|
||||
};
|
||||
|
||||
template <class Name, class Value, class Index>
|
||||
inline values_t<Name,Value,Index>
|
||||
values(Name const& n, Value const& v, Index const& i)
|
||||
{
|
||||
return values_t<Name,Value,Index>(n,v,i);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
// GCC2 has a problem with char (&)[] deduction, so we'll cast string
|
||||
// literals there.
|
||||
#undef S
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# define S(s) (char const*)s
|
||||
#else
|
||||
# define S(s) s
|
||||
#endif
|
||||
|
||||
#endif // BASICS_050424_HPP
|
||||
|
||||
43
test/compose.cpp
Normal file
43
test/compose.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
//~ 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));
|
||||
}
|
||||
114
test/deduced.cpp
Executable file
114
test/deduced.cpp
Executable file
@@ -0,0 +1,114 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
#include "deduced.hpp"
|
||||
|
||||
namespace parameter = boost::parameter;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
BOOST_PARAMETER_NAME(y)
|
||||
BOOST_PARAMETER_NAME(z)
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace parameter;
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, tag::y
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1)
|
||||
, 0
|
||||
, 1
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = not_present, _z = "foo")
|
||||
, _x = 0
|
||||
, "foo"
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1, _z = "foo")
|
||||
, 0
|
||||
, "foo"
|
||||
, 1
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1, _z = "foo")
|
||||
, 0
|
||||
, 1
|
||||
, "foo"
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1, _z = "foo")
|
||||
, 0
|
||||
, _y = 1
|
||||
, "foo"
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1, _z = "foo")
|
||||
, _z = "foo"
|
||||
, _x = 0
|
||||
, 1
|
||||
);
|
||||
|
||||
// Fails becasue of parameters.hpp:428
|
||||
/*
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
|
||||
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1, _z = "foo")
|
||||
, _x = 0
|
||||
, (long*)0
|
||||
, 1
|
||||
);
|
||||
*/
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
77
test/deduced.hpp
Executable file
77
test/deduced.hpp
Executable file
@@ -0,0 +1,77 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_DEDUCED_060920_HPP
|
||||
# define BOOST_DEDUCED_060920_HPP
|
||||
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include "basics.hpp"
|
||||
|
||||
struct not_present_tag {};
|
||||
not_present_tag not_present;
|
||||
|
||||
template <class E, class ArgPack>
|
||||
struct assert_expected
|
||||
{
|
||||
assert_expected(E const& e, ArgPack const& args)
|
||||
: expected(e)
|
||||
, args(args)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
bool check_not_present(T const&) const
|
||||
{
|
||||
BOOST_MPL_ASSERT((boost::is_same<T,not_present_tag>));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
bool check1(K const& k, not_present_tag const&, long) const
|
||||
{
|
||||
return check_not_present(args[k | not_present]);
|
||||
}
|
||||
|
||||
template <class K, class Expected>
|
||||
bool check1(K const& k, Expected const& expected, int) const
|
||||
{
|
||||
return test::equal(args[k], expected);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
void operator()(K) const
|
||||
{
|
||||
boost::parameter::keyword<K> const& k = boost::parameter::keyword<K>::get();
|
||||
assert(check1(k, expected[k], 0L));
|
||||
}
|
||||
|
||||
E const& expected;
|
||||
ArgPack const& args;
|
||||
};
|
||||
|
||||
template <class E, class ArgPack>
|
||||
void check0(E const& e, ArgPack const& args)
|
||||
{
|
||||
boost::mpl::for_each<E>(assert_expected<E,ArgPack>(e, args));
|
||||
}
|
||||
|
||||
template <class P, class E, class A0>
|
||||
void check(E const& e, A0 const& a0)
|
||||
{
|
||||
check0(e, P()(a0));
|
||||
}
|
||||
|
||||
template <class P, class E, class A0, class A1>
|
||||
void check(E const& e, A0 const& a0, A1 const& a1)
|
||||
{
|
||||
check0(e, P()(a0,a1));
|
||||
}
|
||||
|
||||
template <class P, class E, class A0, class A1, class A2>
|
||||
void check(E const& e, A0 const& a0, A1 const& a1, A2 const& a2)
|
||||
{
|
||||
check0(e, P()(a0,a1,a2));
|
||||
}
|
||||
|
||||
#endif // BOOST_DEDUCED_060920_HPP
|
||||
|
||||
109
test/deduced_dependent_predicate.cpp
Executable file
109
test/deduced_dependent_predicate.cpp
Executable file
@@ -0,0 +1,109 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "deduced.hpp"
|
||||
|
||||
namespace parameter = boost::parameter;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
BOOST_PARAMETER_NAME(y)
|
||||
BOOST_PARAMETER_NAME(z)
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace parameter;
|
||||
using boost::is_same;
|
||||
using boost::remove_reference;
|
||||
using boost::add_reference;
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, optional<
|
||||
deduced<tag::y>
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
, is_same<
|
||||
mpl::_1
|
||||
, remove_reference<binding<mpl::_2,tag::x> >
|
||||
>
|
||||
#else
|
||||
, is_same<
|
||||
add_reference<mpl::_1>
|
||||
, binding<mpl::_2,tag::x>
|
||||
>
|
||||
#endif
|
||||
>
|
||||
>
|
||||
>(
|
||||
(_x = 0, _y = 1)
|
||||
, 0
|
||||
, 1
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, optional<
|
||||
deduced<tag::y>
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
, is_same<
|
||||
mpl::_1
|
||||
, remove_reference<binding<mpl::_2,tag::x> >
|
||||
>
|
||||
#else
|
||||
, is_same<
|
||||
add_reference<mpl::_1>
|
||||
, binding<mpl::_2,tag::x>
|
||||
>
|
||||
#endif
|
||||
>
|
||||
>
|
||||
>(
|
||||
(_x = 0U, _y = 1U)
|
||||
, 0U
|
||||
, 1U
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, optional<
|
||||
deduced<tag::y>
|
||||
, is_same<
|
||||
mpl::_1
|
||||
, tag::x::_
|
||||
>
|
||||
>
|
||||
>
|
||||
>(
|
||||
(_x = 0U, _y = 1U)
|
||||
, 0U
|
||||
, 1U
|
||||
);
|
||||
|
||||
check<
|
||||
parameters<
|
||||
tag::x
|
||||
, optional<
|
||||
deduced<tag::y>
|
||||
, is_same<
|
||||
mpl::_1
|
||||
, tag::x::_1
|
||||
>
|
||||
>
|
||||
>
|
||||
>(
|
||||
(_x = 0U, _y = 1U)
|
||||
, 0U
|
||||
, 1U
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
25
test/deduced_unmatched_arg.cpp
Executable file
25
test/deduced_unmatched_arg.cpp
Executable file
@@ -0,0 +1,25 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
|
||||
namespace parameter = boost::parameter;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace parameter;
|
||||
using boost::is_convertible;
|
||||
using mpl::_;
|
||||
|
||||
parameters<
|
||||
optional<
|
||||
deduced<tag::x>, is_convertible<_,int>
|
||||
>
|
||||
>()("foo");
|
||||
}
|
||||
|
||||
24
test/duplicates.cpp
Executable file
24
test/duplicates.cpp
Executable file
@@ -0,0 +1,24 @@
|
||||
// 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.hpp>
|
||||
#include <string.h>
|
||||
#include "basics.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
template <class Params>
|
||||
void f(Params const &) {}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace test;
|
||||
|
||||
f((name = 1, value = 1, test::index = 1, tester = 1,
|
||||
value = 1 // repeated keyword: should not compile
|
||||
));
|
||||
return 0;
|
||||
}
|
||||
|
||||
56
test/earwicker.cpp
Executable file
56
test/earwicker.cpp
Executable file
@@ -0,0 +1,56 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/parameter.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace test {
|
||||
|
||||
BOOST_PARAMETER_KEYWORD(tag, x)
|
||||
BOOST_PARAMETER_KEYWORD(tag, y)
|
||||
BOOST_PARAMETER_KEYWORD(tag, z)
|
||||
|
||||
using namespace boost::parameter;
|
||||
using namespace boost::mpl::placeholders;
|
||||
|
||||
struct f_parameters // vc6 is happier with inheritance than with a typedef
|
||||
: parameters<
|
||||
optional<tag::x,boost::is_convertible<_,int> >
|
||||
, optional<tag::y,boost::is_convertible<_,int> >
|
||||
, optional<tag::z,boost::is_convertible<_,int> >
|
||||
>
|
||||
{};
|
||||
|
||||
#ifdef BOOST_NO_VOID_RETURNS
|
||||
BOOST_PARAMETER_FUN(int, f, 0, 3, f_parameters)
|
||||
#else
|
||||
BOOST_PARAMETER_FUN(void, f, 0, 3, f_parameters)
|
||||
#endif
|
||||
{
|
||||
std::cout << "x = " << p[x | -1] << std::endl;
|
||||
std::cout << "y = " << p[y | -2] << std::endl;
|
||||
std::cout << "z = " << p[z | -3] << std::endl;
|
||||
std::cout << "================" << std::endl;
|
||||
#ifdef BOOST_NO_VOID_RETURNS
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace test;
|
||||
f(x = 1, y = 2, z = 3);
|
||||
f(x = 1);
|
||||
f(y = 2);
|
||||
f(z = 3);
|
||||
f(z = 3, x = 1);
|
||||
}
|
||||
|
||||
|
||||
195
test/efficiency.cpp
Executable file
195
test/efficiency.cpp
Executable file
@@ -0,0 +1,195 @@
|
||||
// Copyright David Abrahams, Matthias Troyer, Michael Gauckler
|
||||
// 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)
|
||||
|
||||
#include <boost/parameter.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace test
|
||||
{
|
||||
//
|
||||
// This test measures the abstraction overhead of using the named
|
||||
// parameter interface. Some actual test results have been recorded
|
||||
// in timings.txt in this source file's directory, or
|
||||
// http://www.boost.org/libs/parameter/test/timings.txt.
|
||||
//
|
||||
// Caveats:
|
||||
//
|
||||
// 1. This test penalizes the named parameter library slightly, by
|
||||
// passing two arguments through the named interface, while
|
||||
// only passing one through the plain C++ interface.
|
||||
//
|
||||
// 2. This test does not measure the case where an ArgumentPack is
|
||||
// so large that it doesn't fit in the L1 cache.
|
||||
//
|
||||
// 3. Although we've tried to make this test as general as
|
||||
// possible, we are targeting it at a specific application.
|
||||
// Where that affects design decisions, we've noted it below in
|
||||
// ***...***.
|
||||
//
|
||||
// 4. The first time you run this program, the time may not be
|
||||
// representative because of disk and memory cache effects, so
|
||||
// always run it multiple times and ignore the first
|
||||
// measurement. This approach will also allow you to estimate
|
||||
// the statistical error of your test by observing the
|
||||
// variation in the valid times.
|
||||
//
|
||||
// 5. Try to run this program on a machine that's otherwise idle,
|
||||
// or other processes and even device hardware interrupts may
|
||||
// interfere by causing caches to be flushed.
|
||||
|
||||
// Accumulator function object with plain C++ interface
|
||||
template <class T>
|
||||
struct plain_weight_running_total
|
||||
{
|
||||
plain_weight_running_total()
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
: sum(T())
|
||||
#else
|
||||
: sum()
|
||||
#endif
|
||||
{}
|
||||
|
||||
void operator()(T w)
|
||||
{
|
||||
this->sum += w;
|
||||
}
|
||||
|
||||
T sum;
|
||||
};
|
||||
|
||||
BOOST_PARAMETER_KEYWORD(tag, weight)
|
||||
BOOST_PARAMETER_KEYWORD(tag, value)
|
||||
|
||||
// Accumulator function object with named parameter interface
|
||||
template <class T>
|
||||
struct named_param_weight_running_total
|
||||
{
|
||||
named_param_weight_running_total()
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
: sum(T())
|
||||
#else
|
||||
: sum()
|
||||
#endif
|
||||
{}
|
||||
|
||||
template <class ArgumentPack>
|
||||
void operator()(ArgumentPack const& variates)
|
||||
{
|
||||
this->sum += variates[weight];
|
||||
}
|
||||
|
||||
T sum;
|
||||
};
|
||||
|
||||
// This value is required to ensure that a smart compiler's dead
|
||||
// code elimination doesn't optimize away anything we're testing.
|
||||
// We'll use it to compute the return code of the executable to make
|
||||
// sure it's needed.
|
||||
double live_code;
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Strategy: because the sum in an accumulator after each call
|
||||
// depends on the previous value of the sum, the CPU's pipeline
|
||||
// might be stalled while waiting for the previous addition to
|
||||
// complete. Therefore, we allocate an array of accumulators,
|
||||
// and update them in sequence, so that there's no dependency
|
||||
// between adjacent addition operations.
|
||||
//
|
||||
// Additionally, if there were only one accumulator, the
|
||||
// compiler or CPU might decide to update the value in a
|
||||
// register rather that writing it back to memory. we want each
|
||||
// operation to at least update the L1 cache. *** Note: This
|
||||
// concern is specific to the particular application at which
|
||||
// we're targeting the test. ***
|
||||
|
||||
// This has to be at least as large as the number of
|
||||
// simultaneous accumulations that can be executing in the
|
||||
// compiler pipeline. A safe number here is larger than the
|
||||
// machine's maximum pipeline depth. If you want to test the L2
|
||||
// or L3 cache, or main memory, you can increase the size of
|
||||
// this array. 1024 is an upper limit on the pipeline depth of
|
||||
// current vector machines.
|
||||
const std::size_t number_of_accumulators = 1024;
|
||||
|
||||
Accumulator a[number_of_accumulators];
|
||||
|
||||
for (long iteration = 0; iteration < repeats; ++iteration)
|
||||
{
|
||||
for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
|
||||
{
|
||||
(*ap)(x);
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate all the partial sums to avoid dead code
|
||||
// elimination.
|
||||
for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
|
||||
{
|
||||
live_code += ap->sum;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Now start a timer
|
||||
boost::timer time;
|
||||
hammer<Accumulator>(x, repeats); // This time, we'll measure
|
||||
return time.elapsed();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
<< std::endl;
|
||||
|
||||
std::cout
|
||||
<< "named parameter time: "
|
||||
<< measure<named_param_weight_running_total<double> >(
|
||||
(weight = .1, value = .2), repeats
|
||||
)
|
||||
<< std::endl;
|
||||
|
||||
// This is ultimately responsible for preventing all the test code
|
||||
// from being optimized away. Change this to return 0 and you
|
||||
// unplug the whole test's life support system.
|
||||
return live_code < 0.;
|
||||
}
|
||||
57
test/macros.cpp
Executable file
57
test/macros.cpp
Executable file
@@ -0,0 +1,57 @@
|
||||
// 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/macros.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <cassert>
|
||||
#include <string.h>
|
||||
|
||||
#include "basics.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
BOOST_PARAMETER_FUN(int, f, 2, 4, f_parameters)
|
||||
{
|
||||
p[tester](
|
||||
p[name]
|
||||
, p[value || boost::bind(&value_default) ]
|
||||
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
|
||||
, p[test::index | 999 ]
|
||||
#else
|
||||
, p[index | 999 ]
|
||||
#endif
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
int main()
|
||||
{
|
||||
using test::f;
|
||||
using test::name;
|
||||
using test::value;
|
||||
using test::index;
|
||||
using test::tester;
|
||||
|
||||
f(
|
||||
test::values(S("foo"), S("bar"), S("baz"))
|
||||
, S("foo"), S("bar"), S("baz")
|
||||
);
|
||||
|
||||
int x = 56;
|
||||
f(
|
||||
test::values("foo", 666.222, 56)
|
||||
, index = boost::ref(x), name = "foo"
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
35
test/maybe.cpp
Executable file
35
test/maybe.cpp
Executable file
@@ -0,0 +1,35 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
80
test/mpl.cpp
Executable file
80
test/mpl.cpp
Executable file
@@ -0,0 +1,80 @@
|
||||
// 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)
|
||||
|
||||
#include "basics.hpp"
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
|
||||
# include <boost/mpl/contains.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template <class Set>
|
||||
struct assert_in_set
|
||||
{
|
||||
template <class T>
|
||||
void operator()(T*)
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::contains<Set,T>));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class Expected, class Params>
|
||||
void f_impl(Params const& p BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
|
||||
{
|
||||
BOOST_MPL_ASSERT_RELATION(
|
||||
mpl::size<Expected>::value
|
||||
, ==
|
||||
, mpl::size<Params>::value
|
||||
);
|
||||
|
||||
mpl::for_each<Params, boost::add_pointer<mpl::_1> >(assert_in_set<Expected>());
|
||||
}
|
||||
|
||||
template<class Expected, class Tester, class Name, class Value, class Index>
|
||||
void f(Tester const& t, const Name& name_,
|
||||
const Value& value_, const Index& index_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
|
||||
{
|
||||
f_impl<Expected>(f_parameters()(t, name_, value_, index_));
|
||||
}
|
||||
|
||||
template<class Expected, class Tester, class Name, class Value>
|
||||
void f(Tester const& t, const Name& name_, const Value& value_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
|
||||
{
|
||||
f_impl<Expected>(f_parameters()(t, name_, value_));
|
||||
}
|
||||
|
||||
template<class Expected, class Tester, class Name>
|
||||
void f(Tester const& t, const Name& name_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
|
||||
{
|
||||
f_impl<Expected>(f_parameters()(t, name_));
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef test::tag::tester tester_;
|
||||
typedef test::tag::name name_;
|
||||
typedef test::tag::value value_;
|
||||
typedef test::tag::index index_;
|
||||
|
||||
f<mpl::list4<tester_,name_,value_,index_> >(1, 2, 3, 4);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test::run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
85
test/normalized_argument_types.cpp
Executable file
85
test/normalized_argument_types.cpp
Executable file
@@ -0,0 +1,85 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct count_instances
|
||||
{
|
||||
count_instances()
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
count_instances(count_instances const&)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
count_instances(T const&)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
~count_instances()
|
||||
{
|
||||
--count;
|
||||
}
|
||||
|
||||
static std::size_t count;
|
||||
};
|
||||
|
||||
std::size_t count_instances::count = 0;
|
||||
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
BOOST_PARAMETER_NAME(y)
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), f, tag,
|
||||
(required
|
||||
(x, (int))
|
||||
(y, (int))
|
||||
)
|
||||
)
|
||||
{
|
||||
BOOST_MPL_ASSERT((boost::is_same<x_type,int>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<y_type,int>));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), g, tag,
|
||||
(required
|
||||
(x, (count_instances))
|
||||
)
|
||||
)
|
||||
{
|
||||
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances>));
|
||||
assert(count_instances::count > 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), h, tag,
|
||||
(required
|
||||
(x, (count_instances const&))
|
||||
)
|
||||
)
|
||||
{
|
||||
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances const>));
|
||||
assert(count_instances::count == 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f(1, 2);
|
||||
f(1., 2.f);
|
||||
f(1U, 2L);
|
||||
|
||||
g(0);
|
||||
|
||||
h(0);
|
||||
}
|
||||
|
||||
110
test/ntp.cpp
Executable file
110
test/ntp.cpp
Executable file
@@ -0,0 +1,110 @@
|
||||
// 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)
|
||||
>));
|
||||
|
||||
73
test/optional_deduced_sfinae.cpp
Executable file
73
test/optional_deduced_sfinae.cpp
Executable file
@@ -0,0 +1,73 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter/preprocessor.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <string>
|
||||
#include "basics.hpp"
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace test {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
using mpl::_;
|
||||
using boost::is_convertible;
|
||||
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
|
||||
// Sun has problems with this syntax:
|
||||
//
|
||||
// template1< r* ( template2<x> ) >
|
||||
//
|
||||
// Workaround: factor template2<x> into a separate typedef
|
||||
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
|
||||
|
||||
typedef is_convertible<_,char const*> predicate;
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), sfinae, tag,
|
||||
(deduced
|
||||
(optional (x, *(predicate), 0))
|
||||
)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), sfinae, tag,
|
||||
(deduced
|
||||
(optional (x, *(is_convertible<_,char const*>), 0))
|
||||
)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class A0>
|
||||
typename boost::enable_if<boost::is_same<int,A0>, int>::type
|
||||
sfinae(A0 const& a0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace test;
|
||||
|
||||
assert(sfinae() == 1);
|
||||
assert(sfinae("foo") == 1);
|
||||
assert(sfinae(1) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
482
test/preprocessor.cpp
Executable file
482
test/preprocessor.cpp
Executable file
@@ -0,0 +1,482 @@
|
||||
// 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")
|
||||
);
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
assert(sfinae("foo") == 1);
|
||||
assert(sfinae(1) == 0);
|
||||
|
||||
# if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
|
||||
// Sun actually eliminates the desired overload for some reason.
|
||||
// Disabling this part of the test because SFINAE abilities are
|
||||
// not the point of this test.
|
||||
assert(sfinae1("foo") == 1);
|
||||
# endif
|
||||
|
||||
assert(sfinae1(1) == 0);
|
||||
#endif
|
||||
|
||||
lazy_defaults(
|
||||
name = udt(0,1)
|
||||
);
|
||||
|
||||
lazy_defaults(
|
||||
name = 0
|
||||
, value = 1
|
||||
, test::index = 2
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
171
test/preprocessor_deduced.cpp
Executable file
171
test/preprocessor_deduced.cpp
Executable file
@@ -0,0 +1,171 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/parameter/preprocessor.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <string>
|
||||
#include "basics.hpp"
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
# include <boost/utility/enable_if.hpp>
|
||||
#endif
|
||||
|
||||
namespace test {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
using mpl::_;
|
||||
using boost::is_convertible;
|
||||
|
||||
BOOST_PARAMETER_NAME(expected)
|
||||
BOOST_PARAMETER_NAME(x)
|
||||
BOOST_PARAMETER_NAME(y)
|
||||
BOOST_PARAMETER_NAME(z)
|
||||
|
||||
// Sun has problems with this syntax:
|
||||
//
|
||||
// template1< r* ( template2<x> ) >
|
||||
//
|
||||
// Workaround: factor template2<x> into a separate typedef
|
||||
typedef is_convertible<_, int> predicate1;
|
||||
typedef is_convertible<_, std::string> predicate2;
|
||||
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), f, tag,
|
||||
(required
|
||||
(expected, *)
|
||||
)
|
||||
(deduced
|
||||
(required
|
||||
(x, *(predicate1))
|
||||
(y, *(predicate2))
|
||||
)
|
||||
)
|
||||
)
|
||||
#else
|
||||
BOOST_PARAMETER_FUNCTION((int), f, tag,
|
||||
(required
|
||||
(expected, *)
|
||||
)
|
||||
(deduced
|
||||
(required
|
||||
(x, *(is_convertible<_, int>))
|
||||
(y, *(is_convertible<_, std::string>))
|
||||
)
|
||||
)
|
||||
)
|
||||
#endif
|
||||
{
|
||||
assert(equal(x, boost::tuples::get<0>(expected)));
|
||||
assert(equal(y, boost::tuples::get<1>(expected)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int x = -1)
|
||||
: x(x)
|
||||
{}
|
||||
|
||||
bool operator==(X const& other) const
|
||||
{
|
||||
return x == other.x;
|
||||
}
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
typedef is_convertible<_, X> predicate3; // SunPro workaround; see above
|
||||
|
||||
BOOST_PARAMETER_FUNCTION((int), g, tag,
|
||||
(required
|
||||
(expected, *)
|
||||
)
|
||||
(deduced
|
||||
(required
|
||||
(x, *(is_convertible<_, int>))
|
||||
(y, *(is_convertible<_, std::string>))
|
||||
)
|
||||
(optional
|
||||
(z, *(predicate3), X())
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
assert(equal(x, boost::tuples::get<0>(expected)));
|
||||
assert(equal(y, boost::tuples::get<1>(expected)));
|
||||
assert(equal(z, boost::tuples::get<2>(expected)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOST_PARAMETER_FUNCTION(
|
||||
(int), sfinae, tag,
|
||||
(deduced
|
||||
(required
|
||||
(x, *(predicate2))
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
// On compilers that actually support SFINAE, add another overload
|
||||
// that is an equally good match and can only be in the overload set
|
||||
// when the others are not. This tests that the SFINAE is actually
|
||||
// working. On all other compilers we're just checking that
|
||||
// everything about SFINAE-enabled code will work, except of course
|
||||
// the SFINAE.
|
||||
template<class A0>
|
||||
typename boost::enable_if<boost::is_same<int,A0>, int>::type
|
||||
sfinae(A0 const& a0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace test
|
||||
|
||||
using boost::make_tuple;
|
||||
|
||||
// make_tuple doesn't work with char arrays.
|
||||
char const* str(char const* s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace test;
|
||||
|
||||
f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
|
||||
f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
|
||||
f(make_tuple(0, str("foo")), 0, "foo");
|
||||
f(make_tuple(0, str("foo")), "foo", 0);
|
||||
f(make_tuple(0, str("foo")), _y = "foo", 0);
|
||||
f(make_tuple(0, str("foo")), _x = 0, "foo");
|
||||
f(make_tuple(0, str("foo")), 0, _y = "foo");
|
||||
|
||||
g(make_tuple(0, str("foo"), X()), _x = 0, _y = "foo");
|
||||
g(make_tuple(0, str("foo"), X()), 0, "foo");
|
||||
g(make_tuple(0, str("foo"), X()), "foo", 0);
|
||||
g(make_tuple(0, str("foo"), X()), _y = "foo", 0);
|
||||
g(make_tuple(0, str("foo"), X()), _x = 0, "foo");
|
||||
g(make_tuple(0, str("foo"), X()), 0, _y = "foo");
|
||||
|
||||
g(make_tuple(0, str("foo"), X(1)), 0, _y = "foo", X(1));
|
||||
g(make_tuple(0, str("foo"), X(1)), X(1), 0, _y = "foo");
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
assert(sfinae("foo") == 1);
|
||||
assert(sfinae(0) == 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
171
test/python_test.cpp
Executable file
171
test/python_test.cpp
Executable file
@@ -0,0 +1,171 @@
|
||||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/parameter/preprocessor.hpp>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/parameter/python.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace test {
|
||||
|
||||
BOOST_PARAMETER_KEYWORD(tags, x)
|
||||
BOOST_PARAMETER_KEYWORD(tags, y)
|
||||
BOOST_PARAMETER_KEYWORD(tags, z)
|
||||
|
||||
struct Xbase
|
||||
{
|
||||
// We need the disable_if part for VC7.1/8.0.
|
||||
template <class Args>
|
||||
Xbase(
|
||||
Args const& args
|
||||
, typename boost::disable_if<
|
||||
boost::is_base_and_derived<Xbase, Args>
|
||||
>::type* = 0
|
||||
)
|
||||
: value(std::string(args[x | "foo"]) + args[y | "bar"])
|
||||
{}
|
||||
|
||||
std::string value;
|
||||
};
|
||||
|
||||
struct X : Xbase
|
||||
{
|
||||
BOOST_PARAMETER_CONSTRUCTOR(X, (Xbase), tags,
|
||||
(optional
|
||||
(x, *)
|
||||
(y, *)
|
||||
)
|
||||
)
|
||||
|
||||
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tags,
|
||||
(required
|
||||
(x, *)
|
||||
(y, *)
|
||||
)
|
||||
(optional
|
||||
(z, *)
|
||||
)
|
||||
)
|
||||
{
|
||||
return args[x] + args[y] + args[z | 0];
|
||||
}
|
||||
|
||||
BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((std::string), g, tags,
|
||||
(optional
|
||||
(x, *)
|
||||
(y, *)
|
||||
)
|
||||
)
|
||||
{
|
||||
return std::string(args[x | "foo"]) + args[y | "bar"];
|
||||
}
|
||||
|
||||
BOOST_PARAMETER_MEMBER_FUNCTION((X&), h, tags,
|
||||
(optional (x, *, "") (y, *, ""))
|
||||
)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class A0>
|
||||
X& operator()(A0 const& a0)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
struct f_fwd
|
||||
{
|
||||
template <class R, class T, class A0, class A1, class A2>
|
||||
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1, A2 const& a2)
|
||||
{
|
||||
return self.f(a0,a1,a2);
|
||||
}
|
||||
};
|
||||
|
||||
struct g_fwd
|
||||
{
|
||||
template <class R, class T, class A0, class A1>
|
||||
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1)
|
||||
{
|
||||
return self.g(a0,a1);
|
||||
}
|
||||
};
|
||||
|
||||
struct h_fwd
|
||||
{
|
||||
template <class R, class T>
|
||||
R operator()(boost::type<R>, T& self)
|
||||
{
|
||||
return self.h();
|
||||
}
|
||||
|
||||
template <class R, class T, class A0>
|
||||
R operator()(boost::type<R>, T& self, A0 const& a0)
|
||||
{
|
||||
return self.h(a0);
|
||||
}
|
||||
|
||||
template <class R, class T, class A0, class A1>
|
||||
R operator()(boost::type<R>, T& self, A0 const& a0, A1 const& a1)
|
||||
{
|
||||
return self.h(a0,a1);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(python_test_ext)
|
||||
{
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace test;
|
||||
using namespace boost::python;
|
||||
|
||||
class_<X>("X")
|
||||
.def(
|
||||
boost::parameter::python::init<
|
||||
mpl::vector<
|
||||
tags::x*(std::string), tags::y*(std::string)
|
||||
>
|
||||
>()
|
||||
)
|
||||
.def(
|
||||
"f"
|
||||
, boost::parameter::python::function<
|
||||
f_fwd
|
||||
, mpl::vector<
|
||||
int, tags::x(int), tags::y(int), tags::z*(int)
|
||||
>
|
||||
>()
|
||||
)
|
||||
.def(
|
||||
"g"
|
||||
, boost::parameter::python::function<
|
||||
g_fwd
|
||||
, mpl::vector<
|
||||
std::string, tags::x*(std::string), tags::y*(std::string)
|
||||
>
|
||||
>()
|
||||
)
|
||||
.def(
|
||||
"h"
|
||||
, boost::parameter::python::function<
|
||||
h_fwd
|
||||
, mpl::vector<
|
||||
X&, tags::x**(std::string), tags::y**(std::string)
|
||||
>
|
||||
>()
|
||||
, return_arg<>()
|
||||
)
|
||||
.def(
|
||||
boost::parameter::python::call<
|
||||
mpl::vector<
|
||||
X&, tags::x(int)
|
||||
>
|
||||
>() [ return_arg<>() ]
|
||||
)
|
||||
.def_readonly("value", &X::value);
|
||||
}
|
||||
|
||||
41
test/python_test.py
Normal file
41
test/python_test.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright Daniel Wallin 2006. Distributed under the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
'''
|
||||
>>> from python_test_ext import X
|
||||
>>> x = X(y = 'baz')
|
||||
>>> x.value
|
||||
'foobaz'
|
||||
>>> x.f(1,2)
|
||||
3
|
||||
>>> x.f(1,2,3)
|
||||
6
|
||||
>>> x.f(1,2, z = 3)
|
||||
6
|
||||
>>> x.f(z = 3, y = 2, x = 1)
|
||||
6
|
||||
>>> x.g()
|
||||
'foobar'
|
||||
>>> x.g(y = "baz")
|
||||
'foobaz'
|
||||
>>> x.g(x = "baz")
|
||||
'bazbar'
|
||||
>>> x.g(y = "foo", x = "bar")
|
||||
'barfoo'
|
||||
>>> y = x.h(x = "bar", y = "foo")
|
||||
>>> assert x == y
|
||||
>>> y = x(0)
|
||||
>>> assert x == y
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, python_test
|
||||
return doctest.testmod(python_test)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
104
test/sfinae.cpp
Executable file
104
test/sfinae.cpp
Executable file
@@ -0,0 +1,104 @@
|
||||
// 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 <boost/detail/lightweight_test.hpp>
|
||||
#include <string>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
# include <boost/utility/enable_if.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
#endif
|
||||
|
||||
namespace test
|
||||
{
|
||||
BOOST_PARAMETER_KEYWORD(keywords,name)
|
||||
BOOST_PARAMETER_KEYWORD(keywords,value)
|
||||
|
||||
using namespace boost::parameter;
|
||||
|
||||
struct f_parameters
|
||||
: parameters<
|
||||
optional<
|
||||
keywords::name
|
||||
, boost::is_convertible<boost::mpl::_, std::string>
|
||||
>
|
||||
, optional<
|
||||
keywords::value
|
||||
, boost::is_convertible<boost::mpl::_, float>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
// The use of assert_equal_string is just a nasty workaround for a
|
||||
// vc++ 6 ICE.
|
||||
void assert_equal_string(std::string x, std::string y)
|
||||
{
|
||||
BOOST_TEST(x == y);
|
||||
}
|
||||
|
||||
template<class P>
|
||||
void f_impl(P const& p)
|
||||
{
|
||||
float v = p[value | 3.f];
|
||||
BOOST_TEST(v == 3.f);
|
||||
assert_equal_string(p[name | "bar"], "foo");
|
||||
}
|
||||
|
||||
void f()
|
||||
{
|
||||
f_impl(f_parameters()());
|
||||
}
|
||||
|
||||
template<class A0>
|
||||
void f(
|
||||
A0 const& a0
|
||||
, BOOST_PARAMETER_MATCH(f_parameters, (A0), args))
|
||||
{
|
||||
f_impl(args(a0));
|
||||
}
|
||||
|
||||
template<class A0, class A1>
|
||||
void f(
|
||||
A0 const& a0, A1 const& a1
|
||||
, BOOST_PARAMETER_MATCH(f_parameters,(A0)(A1), args))
|
||||
{
|
||||
f_impl(args(a0, a1));
|
||||
}
|
||||
|
||||
#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, class A1>
|
||||
typename boost::enable_if<boost::is_same<int,A0>, int>::type
|
||||
f(A0 const& a0, A1 const& a1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} // namespace test
|
||||
|
||||
int main()
|
||||
{
|
||||
using test::name;
|
||||
using test::value;
|
||||
using test::f;
|
||||
|
||||
f("foo");
|
||||
f("foo", 3.f);
|
||||
f(value = 3.f, name = "foo");
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
BOOST_TEST(f(3, 4) == 0);
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
42
test/singular.cpp
Executable file
42
test/singular.cpp
Executable 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)
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
128
test/timings.txt
Executable file
128
test/timings.txt
Executable file
@@ -0,0 +1,128 @@
|
||||
# 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)
|
||||
|
||||
----------------- Test #1 ----------------
|
||||
Testers:
|
||||
Matthias Troyer, Michael Gauckler, David Abrahams
|
||||
|
||||
Date:
|
||||
2005-09-09
|
||||
|
||||
Compiler:
|
||||
Cygwin g++-4.0.0
|
||||
|
||||
Command lines:
|
||||
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops \
|
||||
-O3 -finline-functions -Wno-inline -DNDEBUG efficiency.cpp
|
||||
|
||||
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
|
||||
|
||||
efficiency && efficiency && efficiency
|
||||
|
||||
Machine:
|
||||
Dell Inspiron 9300
|
||||
Intel(R) Pentium(R) M processor 2.00GHz
|
||||
Running on 230 volts AC power
|
||||
|
||||
Timings:
|
||||
Run #1 results discarded per standard practice
|
||||
|
||||
Run #2
|
||||
plain time: 0.75
|
||||
named parameter time: 0.734
|
||||
|
||||
Run #3
|
||||
plain time: 0.781
|
||||
named parameter time: 0.766
|
||||
|
||||
----------------- Test #2 ----------------
|
||||
|
||||
Testers:
|
||||
Chris Frey
|
||||
|
||||
Date:
|
||||
2005-09-17
|
||||
|
||||
Compiler:
|
||||
Linux kernel 2.4.27
|
||||
gcc version 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8)
|
||||
|
||||
Command lines:
|
||||
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops \
|
||||
-O3 -finline-functions -Wno-inline -DNDEBUG efficiency.cpp
|
||||
|
||||
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
|
||||
|
||||
Machine:
|
||||
IBM Thinkpad 770Z, running on AC power
|
||||
Intel Pentium II 366Mhz
|
||||
|
||||
Timings:
|
||||
Run #1 results discarded per standard practice
|
||||
|
||||
Run #2
|
||||
plain time: 6.42
|
||||
named parameter time: 7.34
|
||||
|
||||
Run #3
|
||||
plain time: 6.42
|
||||
named parameter time: 7.34
|
||||
|
||||
----------------- Test #2 ----------------
|
||||
|
||||
Testers:
|
||||
Stuar Dootson
|
||||
|
||||
Date:
|
||||
2005-09-18
|
||||
|
||||
Machine:
|
||||
Athlon 64 3500+ laptop, running on AC power
|
||||
Windows XP SP2
|
||||
|
||||
|
||||
Compiler: Visual C++ 7.1
|
||||
|
||||
command line:
|
||||
cl -O2 efficiency.cpp -EHsc -I\lib\boost\include\boost-1_33
|
||||
|
||||
Results:
|
||||
plain time: <ignored>
|
||||
named parameter time: <ignored>
|
||||
plain time: 1.453
|
||||
named parameter time: 1.437
|
||||
plain time: 1.453
|
||||
named parameter time: 1.453
|
||||
|
||||
Compiler: Visual C++ 8.0
|
||||
|
||||
command-line:
|
||||
cl -O2 efficiency.cpp -EHsc -I\lib\boost\include\boost-1_33
|
||||
|
||||
Results:
|
||||
plain time: <ignored>
|
||||
named parameter time: <ignored>
|
||||
plain time: 1.438
|
||||
named parameter time: 1.453
|
||||
plain time: 1.438
|
||||
named parameter time: 1.437
|
||||
|
||||
Compiler: Mingw gcc 3.4.2
|
||||
|
||||
command-line:
|
||||
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops -O3
|
||||
-finline-functions -Wno-inline -DNDEBUG efficiency.cpp
|
||||
-I\lib\boost\include\boost-1_33
|
||||
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
|
||||
|
||||
Results:
|
||||
plain time: <ignored>
|
||||
named parameter time: <ignored>
|
||||
plain time: 1.14
|
||||
named parameter time: 1.422
|
||||
plain time: 1.125
|
||||
named parameter time: 1.406
|
||||
|
||||
-----------------------------------------
|
||||
|
||||
38
test/tutorial.cpp
Executable file
38
test/tutorial.cpp
Executable file
@@ -0,0 +1,38 @@
|
||||
// Copyright David Abrahams 2005. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
|
||||
namespace graphs
|
||||
{
|
||||
BOOST_PARAMETER_KEYWORD(tag, graph) // Note: no semicolon
|
||||
BOOST_PARAMETER_KEYWORD(tag, visitor)
|
||||
BOOST_PARAMETER_KEYWORD(tag, root_vertex)
|
||||
BOOST_PARAMETER_KEYWORD(tag, index_map)
|
||||
BOOST_PARAMETER_KEYWORD(tag, color_map)
|
||||
}
|
||||
|
||||
namespace graphs { namespace core
|
||||
{
|
||||
template <class ArgumentPack>
|
||||
void depth_first_search(ArgumentPack const& args)
|
||||
{
|
||||
std::cout << "graph:\t" << args[graph] << std::endl;
|
||||
std::cout << "visitor:\t" << args[visitor] << std::endl;
|
||||
std::cout << "root_vertex:\t" << args[root_vertex] << std::endl;
|
||||
std::cout << "index_map:\t" << args[index_map] << std::endl;
|
||||
std::cout << "color_map:\t" << args[color_map] << std::endl;
|
||||
}
|
||||
}} // graphs::core
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace graphs;
|
||||
|
||||
core::depth_first_search((
|
||||
graph = 'G', visitor = 2, root_vertex = 3.5,
|
||||
index_map = "hello, world", color_map = false));
|
||||
return 0;
|
||||
}
|
||||
30
test/unwrap_cv_reference.cpp
Executable file
30
test/unwrap_cv_reference.cpp
Executable file
@@ -0,0 +1,30 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
using namespace boost::parameter::aux;
|
||||
using namespace boost;
|
||||
struct foo {};
|
||||
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int>::type,int>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const>::type,int const>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int volatile>::type,int volatile>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const volatile>::type,int const volatile>));
|
||||
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo>::type,foo>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const>::type,foo const>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo volatile>::type,foo volatile>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const volatile>::type,foo const volatile>));
|
||||
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> >::type,foo>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const>::type,foo>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> volatile>::type,foo>));
|
||||
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const volatile>::type,foo>));
|
||||
}
|
||||
Reference in New Issue
Block a user