Compare commits

...

67 Commits

Author SHA1 Message Date
Beman Dawes
5a777d3496 Release 1.47.0 beta 1
[SVN r72708]
2011-06-21 13:23:49 +00:00
Marshall Clow
bdcbf442bf Merge fix to release branch, fixes #4983
[SVN r68366]
2011-01-22 15:42:09 +00:00
Andrey Semashev
c9cf0ab0f5 Merged changes from trunk.
[SVN r62272]
2010-05-27 17:58:58 +00:00
Douglas Gregor
20301b3da4 Add some missing includes for the parameter library
[SVN r62231]
2010-05-26 07:47:05 +00:00
Andrey Semashev
59e172adb3 Added missing include.
[SVN r60776]
2010-03-22 20:18:30 +00:00
Troy D. Straszheim
9f4334c1c1 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Daniel James
7ff5c4b996 Merge some missing link/libraries changes. Fixes #2279,#3454.
Merged revisions 52231,53476 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52231 | jewillco | 2009-04-07 17:46:32 +0100 (Tue, 07 Apr 2009) | 1 line
  
  Updating maintainer info for BGL, fixes #2279
........
  r53476 | jewillco | 2009-05-31 02:40:59 +0100 (Sun, 31 May 2009) | 1 line
  
  Fixed more links to property_map
........


[SVN r56226]
2009-09-15 21:16:58 +00:00
Troy D. Straszheim
1b1499b94c Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Troy D. Straszheim
3cf03f73ca merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Dave Abrahams
04cea6497d Merging all parameter changes from trunk. These all look like they
fix bugs, although the one that lets you use the argument pack to
compute a return type was never tested (still isn't).


[SVN r47446]
2008-07-15 16:02:00 +00:00
Daniel James
e6eda9a776 Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Beman Dawes
8a404e2d67 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
31f9f620fe Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
56ddeddfaf Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
fe43dad724 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

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

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

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


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

value_init.hpp:
  Borland workarounds
  Use angle-includes consistently


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

5
doc/Jamfile.v2 Executable file → Normal file
View File

@@ -1,3 +1,6 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import docutils ;
import path ;
@@ -13,7 +16,7 @@ for local b in $(bases)
html $(b) : $(b).rst :
#
<docutils-html>"-gdt --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
<docutils-html>"-gdt --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
;
}

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

File diff suppressed because it is too large Load Diff

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

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

File diff suppressed because it is too large Load Diff

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

@@ -1,3 +1,8 @@
/* Copyright David Abrahams 2006. Distributed under the Boost
Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
@import "../../../../rst.css";
div.section div.section div.section dl {
@@ -14,8 +19,12 @@ img {
}
span.vellipsis {
line-height: 30% ;
font-size: 200% ;
display: block;
width: 5px;
height: 22px;
background: url("vellipsis.gif");
margin-left: 3em;
text-indent: -1000px;
}

BIN
doc/html/vellipsis.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 B

2828
doc/index.rst Executable file → Normal file

File diff suppressed because it is too large Load Diff

778
doc/python.rst Normal file
View File

@@ -0,0 +1,778 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The Boost Parameter Library Python Binding Documentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
:Authors: David Abrahams, Daniel Wallin
:Contact: dave@boost-consulting.com, daniel@boostpro.com
:organization: `BoostPro Computing`_
:date: $Date$
:copyright: Copyright David Abrahams, Daniel Wallin
2005-2009. Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at http://www.boost.org/LICENSE_1_0.txt)
:abstract: Makes it possible to bind Boost.Parameter-enabled
functions, operators and constructors to Python.
|(logo)|__
.. |(logo)| image:: ../../../../boost.png
:alt: Boost
__ ../../../../index.htm
.. _`BoostPro Computing`: http://www.boostpro.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*.

381
doc/reference.rst Executable file → Normal file
View File

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

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

@@ -3,14 +3,19 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See www.boost.org/libs/parameter for documentation.
#ifndef BOOST_PARAMETER_050401_HPP
#define BOOST_PARAMETER_050401_HPP
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/value_type.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/parameter/match.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/preprocessor.hpp>
#endif // BOOST_PARAMETER_050401_HPP

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

@@ -11,6 +11,7 @@
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/is_maybe.hpp>
#include <boost/parameter/config.hpp>
#include <boost/mpl/apply.hpp>
@@ -21,17 +22,20 @@
#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/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
namespace boost { namespace parameter {
namespace boost { namespace parameter {
// Forward declaration for aux::arg_list, below.
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
@@ -42,7 +46,7 @@ namespace aux {
// declarations to build member function overload sets that can
// match against keywords.
//
// MPL sequence support
struct arg_list_tag;
@@ -67,7 +71,7 @@ struct empty_arg_list
// lookup given that default
struct binding
{
template<class KW, class Default>
template<class KW, class Default, class Reference>
struct apply
{
typedef Default type;
@@ -79,14 +83,14 @@ struct empty_arg_list
template <class KW>
static no_tag has_key(KW*);
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| (BOOST_WORKAROUND(__GNUC__, < 3)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// The overload set technique doesn't work with these older
// compilers, so they need some explicit handholding.
// A metafunction class that, given a keyword, returns the type
// of the base sublist whose get() function can produce the
// value for that key
@@ -137,9 +141,9 @@ struct empty_arg_list
// was found if we match this overload, so unless that parameter
// has a default, we indicate that the actual arguments don't
// match the function's requirements.
template <class ParameterRequirements>
template <class ParameterRequirements, class ArgPack>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
satisfies(ParameterRequirements*, ArgPack*);
// MPL sequence support
typedef empty_arg_list type; // convenience
@@ -155,15 +159,6 @@ no_tag operator*(empty_arg_list, KW*);
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
{
@@ -176,7 +171,7 @@ template <class TaggedArg, class Next = empty_arg_list>
struct arg_list : Next
{
typedef arg_list<TaggedArg,Next> self;
typedef typename TaggedArg::key_type key_type;
typedef typename TaggedArg::key_type key_type;
typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;
@@ -211,9 +206,9 @@ struct arg_list : Next
// Create a new list by prepending arg to a copy of tail. Used
// when incrementally building this structure with the comma
// operator.
arg_list(TaggedArg arg, Next const& tail)
arg_list(TaggedArg head, Next const& tail)
: Next(tail)
, arg(arg)
, arg(head)
{}
// A metafunction class that, given a keyword and a default
@@ -221,13 +216,13 @@ struct arg_list : Next
// lookup given that default
struct binding
{
template <class KW, class Default>
template <class KW, class Default, class Reference>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
, mpl::if_<Reference, reference, value_type>
, mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
>::type type;
};
};
@@ -241,8 +236,8 @@ struct arg_list : Next
// 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)
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
# endif
BOOST_MPL_ASSERT_MSG(
@@ -257,7 +252,7 @@ struct arg_list : Next
// specific arguments by name
//
// Helpers that handle the case when TaggedArg is
// Helpers that handle the case when TaggedArg is
// empty<T>.
template <class D>
reference get_default(D const&, mpl::false_) const
@@ -297,7 +292,7 @@ struct arg_list : Next
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap2<binding, KW, void_>::type
typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
operator[](keyword<KW> const& x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
@@ -305,7 +300,7 @@ struct arg_list : Next
}
template <class KW, class Default>
typename mpl::apply_wrap2<binding, KW, Default&>::type
typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
operator[](default_<KW, Default> x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
@@ -313,9 +308,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
{
@@ -336,7 +332,7 @@ struct arg_list : Next
template <class Default>
reference get(default_<key_type,Default> const& d) const
{
return get_default(d, holds_maybe());
return get_default(d, holds_maybe());
}
template <class Default>
@@ -344,7 +340,7 @@ struct arg_list : Next
{
return arg.value;
}
#else
reference operator[](keyword<key_type> const&) const
@@ -381,10 +377,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
@@ -395,7 +395,7 @@ struct arg_list : Next
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class KW, class T2>
arg_list<tagged_argument<KW, T2>, self>
arg_list<tagged_argument<KW, T2>, self>
operator,(tagged_argument<KW,T2> x) const
{
return arg_list<tagged_argument<KW,T2>, self>(x, *this);
@@ -409,7 +409,7 @@ struct arg_list : Next
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
template <> struct arg_list<int,int> {};
#endif
#endif
// MPL sequence support
template <class ArgumentPack>
@@ -419,7 +419,7 @@ struct arg_list_iterator
// The incremented iterator
typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
// dereferencing yields the key type
typedef typename ArgumentPack::key_type type;
};

View File

@@ -0,0 +1,131 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_CAST_060902_HPP
# define BOOST_PARAMETER_CAST_060902_HPP
# include <boost/detail/workaround.hpp>
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/remove_const.hpp>
# endif
namespace boost { namespace parameter { namespace aux {
struct use_default_tag {};
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value
# else
// Handles possible implicit casts. Used by preprocessor.hpp to
// normalize user input.
//
// cast<void*>::execute() is identity
// cast<void*(X)>::execute() is identity
// cast<void(X)>::execute() casts to X
//
// preprocessor.hpp uses this like this:
//
// #define X(value, predicate)
// cast<void predicate>::execute(value)
//
// X(something, *)
// X(something, *(predicate))
// X(something, (int))
template <class T>
struct cast;
template <>
struct cast<void*>
{
static use_default_tag execute(use_default_tag)
{
return use_default_tag();
}
static use_default_tag remove_const(use_default_tag)
{
return use_default_tag();
}
template <class U>
static U& execute(U& value)
{
return value;
}
template <class U>
static U& remove_const(U& x)
{
return x;
}
};
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
typedef void* voidstar;
template <class T>
struct cast<voidstar(T)>
: cast<void*>
{
};
#else
template <class T>
struct cast<void*(T)>
: cast<void*>
{
};
#endif
template <class T>
struct cast<void(T)>
{
typedef typename boost::add_reference<
typename boost::remove_const<T>::type
>::type reference;
static use_default_tag execute(use_default_tag)
{
return use_default_tag();
}
static use_default_tag remove_const(use_default_tag)
{
return use_default_tag();
}
static T execute(T value)
{
return value;
}
template <class U>
static reference remove_const(U const& x)
{
return const_cast<reference>(x);
}
};
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) \
boost::parameter::aux::cast<void predicate>::remove_const( \
boost::parameter::aux::cast<void predicate>::execute(value) \
)
# endif
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_CAST_060902_HPP

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

@@ -4,7 +4,9 @@
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEFAULT_050329_HPP
#define DEFAULT_050329_HPP
# define DEFAULT_050329_HPP
# include <boost/detail/workaround.hpp>
namespace boost { namespace parameter { namespace aux {
@@ -27,7 +29,7 @@ struct default_
// the user when resolving the value of the parameter with the
// given keyword
//
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 300)
# if BOOST_WORKAROUND(__EDG_VERSION__, <= 300)
// These compilers need a little extra help with overload
// resolution; we have empty_arg_list's operator[] accept a base
// class to make that overload less preferable.
@@ -48,8 +50,8 @@ struct lazy_default
: lazy_default_base<KW,DefaultComputer>(x)
{}
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
#else
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
# else
template <class KW, class DefaultComputer>
struct lazy_default
{
@@ -58,8 +60,8 @@ struct lazy_default
{}
DefaultComputer const& compute_default;
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
#endif
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
# endif
}}} // namespace boost::parameter::aux

View File

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin, David Abrahams 2010. 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_IS_MAYBE_050329_HPP
#define BOOST_PARAMETER_IS_MAYBE_050329_HPP
#include <boost/type_traits/is_base_and_derived.hpp>
namespace boost {
namespace parameter {
namespace aux {
struct maybe_base {};
template <class T>
struct is_maybe
: is_base_and_derived<maybe_base, T>
{};
} // namespace aux
} // namespace parameter
} // namespace boost
#endif // BOOST_PARAMETER_IS_MAYBE_050329_HPP

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

@@ -2,34 +2,59 @@
// 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
//
// 2009.10.21 TDS remove depenency on boost::python::detail::referent_storage
//
#ifndef BOOST_PARAMETER_MAYBE_091021_HPP
# define BOOST_PARAMETER_MAYBE_091021_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/type_traits/add_const.hpp>
# include <boost/optional.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/aligned_storage.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/parameter/aux_/is_maybe.hpp>
namespace boost { namespace parameter { namespace aux {
struct maybe_base {};
template <class T> struct referent_size;
template <class T>
struct referent_size<T&>
{
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(T));
};
// A metafunction returning a POD type which can store U, where T ==
// U&. If T is not a reference type, returns a POD which can store T.
template <class T>
struct referent_storage
{
typedef typename boost::aligned_storage<
referent_size<T>::value
>::type type;
};
template <class T>
struct maybe : maybe_base
{
typedef typename mpl::if_<
is_reference<T>
, T
, typename add_reference<
typename add_const<T>::type
>::type
typedef typename add_reference<
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
T const
# else
typename add_const<T>::type
# endif
>::type reference;
explicit maybe(T value)
: value(value)
typedef typename remove_cv<
BOOST_DEDUCED_TYPENAME remove_reference<reference>::type
>::type non_cv_value;
explicit maybe(T value_)
: value(value_)
, constructed(false)
{}
@@ -40,32 +65,31 @@ struct maybe : maybe_base
~maybe()
{
if (constructed)
destroy((void(*)(reference))0);
this->destroy();
}
reference construct(reference value) const
reference construct(reference value_) const
{
return value;
return value_;
}
template <class U, class V>
reference construct(U const& value, void(*)(V&)) const
template <class U>
reference construct2(U const& value_) const
{
new (m_storage.bytes) V(value);
new (m_storage.address()) non_cv_value(value_);
constructed = true;
return *(V*)m_storage.bytes;
return *(non_cv_value*)m_storage.address();
}
template <class U>
reference construct(U const& value) const
reference construct(U const& value_) const
{
return construct(value, (void(*)(reference))0);
return this->construct2(value_);
}
template <class U>
void destroy(void(*)(U&))
void destroy()
{
((U*)m_storage.bytes)->~U();
((non_cv_value*)m_storage.address())->~non_cv_value();
}
typedef reference(maybe<T>::*safe_bool)() const;
@@ -83,7 +107,9 @@ struct maybe : maybe_base
private:
boost::optional<T> value;
mutable bool constructed;
mutable typename boost::python::detail::referent_storage<
mutable typename referent_storage<
reference
>::type m_storage;
};

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

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

View File

View File

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

46
include/boost/parameter/aux_/preprocessor/flatten.hpp Executable file → Normal file
View File

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

1
include/boost/parameter/aux_/preprocessor/for_each.hpp Executable file → Normal file
View File

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

5
include/boost/parameter/aux_/python/invoker.hpp Executable file → Normal file
View File

@@ -8,6 +8,7 @@
# include <boost/mpl/begin.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/mpl/size.hpp>
# include <boost/parameter/keyword.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
@@ -85,9 +86,9 @@ struct invoker<0, M, R, Args>
template <class M, class R, class T, class Args>
struct member_invoker<0, M, R, T, Args>
{
static R execute()
static R execute(T& self)
{
return M()(boost::type<R>());
return M()(boost::type<R>(), self);
}
};

View File

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

View File

@@ -0,0 +1,67 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_SET_060912_HPP
# define BOOST_PARAMETER_SET_060912_HPP
# include <boost/detail/workaround.hpp>
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
&& !BOOST_WORKAROUND(__GNUC__, < 3)
# include <boost/mpl/insert.hpp>
# include <boost/mpl/set/set0.hpp>
# include <boost/mpl/has_key.hpp>
namespace boost { namespace parameter { namespace aux {
typedef mpl::set0<> set0;
template <class Set, class K>
struct insert_
{
typedef typename mpl::insert<Set, K>::type type;
};
template <class Set, class K>
struct has_key_
{
typedef typename mpl::has_key<Set, K>::type type;
};
}}} // namespace boost::parameter::aux
# else
# include <boost/mpl/list.hpp>
# include <boost/mpl/end.hpp>
# include <boost/mpl/find.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/push_front.hpp>
namespace boost { namespace parameter { namespace aux {
typedef mpl::list0<> set0;
template <class Set, class K>
struct insert_
{
typedef typename mpl::push_front<Set, K>::type type;
};
template <class Set, class K>
struct has_key_
{
typedef typename mpl::find<Set, K>::type iter;
typedef mpl::not_<
is_same<iter, typename mpl::end<Set>::type>
> type;
};
}}} // namespace boost::parameter::aux
# endif
#endif // BOOST_PARAMETER_SET_060912_HPP

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

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

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

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

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

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

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

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

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

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

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

@@ -9,7 +9,6 @@
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/noncopyable.hpp>
namespace boost { namespace parameter {
@@ -29,7 +28,7 @@ namespace boost { namespace parameter {
// f(rate = 1, skew = 2.4);
//
template <class Tag>
struct keyword : noncopyable
struct keyword
{
template <class T>
typename aux::tag<Tag, T>::type const
@@ -92,17 +91,18 @@ 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
@@ -111,19 +111,19 @@ struct keyword : noncopyable
#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>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get();
# 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
@@ -140,8 +140,8 @@ struct keyword : noncopyable
} \
namespace \
{ \
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get(); \
::boost::parameter::keyword<tag_namespace::name> const& name \
= ::boost::parameter::keyword<tag_namespace::name>::instance;\
}
#endif

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

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

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

View File

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

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

File diff suppressed because it is too large Load Diff

961
include/boost/parameter/preprocessor.hpp Executable file → Normal file

File diff suppressed because it is too large Load Diff

160
include/boost/parameter/python.hpp Executable file → Normal file
View File

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

View File

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

0
index.html Executable file → Normal file
View File

View File

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

View File

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

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

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

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

@@ -12,6 +12,7 @@
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <cstring>
#include <boost/detail/lightweight_test.hpp>
namespace test {
@@ -79,9 +80,9 @@ struct values_t
BOOST_MPL_ASSERT((boost::is_same<Value,Value_>));
BOOST_MPL_ASSERT((boost::is_same<Name,Name_>));
#endif
BOOST_ASSERT(equal(n, n_));
BOOST_ASSERT(equal(v, v_));
BOOST_ASSERT(equal(i, i_));
BOOST_TEST(equal(n, n_));
BOOST_TEST(equal(v, v_));
BOOST_TEST(equal(i, i_));
}
Name const& n;

114
test/deduced.cpp Normal file
View File

@@ -0,0 +1,114 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#include "deduced.hpp"
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)
int main()
{
using namespace parameter;
check<
parameters<
tag::x
, tag::y
>
>(
(_x = 0, _y = 1)
, 0
, 1
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = not_present, _z = "foo")
, _x = 0
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, "foo"
, 1
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, 1
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, 0
, _y = 1
, "foo"
);
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, _z = "foo"
, _x = 0
, 1
);
// Fails becasue of parameters.hpp:428
/*
check<
parameters<
tag::x
, required<deduced<tag::y>, boost::is_convertible<mpl::_, int> >
, optional<deduced<tag::z>, boost::is_convertible<mpl::_, char const*> >
>
>(
(_x = 0, _y = 1, _z = "foo")
, _x = 0
, (long*)0
, 1
);
*/
return 0;
};

77
test/deduced.hpp Normal file
View File

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

View File

@@ -0,0 +1,109 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/type_traits.hpp>
#include "deduced.hpp"
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)
int main()
{
using namespace parameter;
using boost::is_same;
using boost::remove_reference;
using boost::add_reference;
check<
parameters<
tag::x
, optional<
deduced<tag::y>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, is_same<
mpl::_1
, remove_reference<binding<mpl::_2,tag::x> >
>
#else
, is_same<
add_reference<mpl::_1>
, binding<mpl::_2,tag::x>
>
#endif
>
>
>(
(_x = 0, _y = 1)
, 0
, 1
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, is_same<
mpl::_1
, remove_reference<binding<mpl::_2,tag::x> >
>
#else
, is_same<
add_reference<mpl::_1>
, binding<mpl::_2,tag::x>
>
#endif
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
, is_same<
mpl::_1
, tag::x::_
>
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
check<
parameters<
tag::x
, optional<
deduced<tag::y>
, is_same<
mpl::_1
, tag::x::_1
>
>
>
>(
(_x = 0U, _y = 1U)
, 0U
, 1U
);
return 0;
}

View File

@@ -0,0 +1,25 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/name.hpp>
namespace parameter = boost::parameter;
namespace mpl = boost::mpl;
BOOST_PARAMETER_NAME(x)
int main()
{
using namespace parameter;
using boost::is_convertible;
using mpl::_;
parameters<
optional<
deduced<tag::x>, is_convertible<_,int>
>
>()("foo");
}

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

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

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

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

1
test/maybe.cpp Executable file → Normal file
View File

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

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

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

View File

@@ -0,0 +1,85 @@
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <cassert>
struct count_instances
{
count_instances()
{
++count;
}
count_instances(count_instances const&)
{
++count;
}
template <class T>
count_instances(T const&)
{
++count;
}
~count_instances()
{
--count;
}
static std::size_t count;
};
std::size_t count_instances::count = 0;
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_FUNCTION((int), f, tag,
(required
(x, (int))
(y, (int))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,int>));
BOOST_MPL_ASSERT((boost::is_same<y_type,int>));
return 0;
}
BOOST_PARAMETER_FUNCTION((int), g, tag,
(required
(x, (count_instances))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances>));
assert(count_instances::count > 0);
return 0;
}
BOOST_PARAMETER_FUNCTION((int), h, tag,
(required
(x, (count_instances const&))
)
)
{
BOOST_MPL_ASSERT((boost::is_same<x_type,count_instances const>));
assert(count_instances::count == 1);
return 0;
}
int main()
{
f(1, 2);
f(1., 2.f);
f(1U, 2L);
g(0);
h(0);
}

9
test/ntp.cpp Executable file → Normal file
View File

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

View File

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

283
test/preprocessor.cpp Executable file → Normal file
View File

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

View File

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

View File

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

View File

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

171
test/python_test.cpp Normal file
View File

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

41
test/python_test.py Normal file
View File

@@ -0,0 +1,41 @@
# Copyright Daniel Wallin 2006. Distributed under the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from python_test_ext import X
>>> x = X(y = 'baz')
>>> x.value
'foobaz'
>>> x.f(1,2)
3
>>> x.f(1,2,3)
6
>>> x.f(1,2, z = 3)
6
>>> x.f(z = 3, y = 2, x = 1)
6
>>> x.g()
'foobar'
>>> x.g(y = "baz")
'foobaz'
>>> x.g(x = "baz")
'bazbar'
>>> x.g(y = "foo", x = "bar")
'barfoo'
>>> y = x.h(x = "bar", y = "foo")
>>> assert x == y
>>> y = x(0)
>>> assert x == y
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, python_test
return doctest.testmod(python_test)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

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

@@ -5,11 +5,11 @@
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <boost/assert.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
#include <boost/type_traits/is_convertible.hpp>
#ifndef BOOST_NO_SFINAE
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
@@ -38,14 +38,14 @@ namespace test
// vc++ 6 ICE.
void assert_equal_string(std::string x, std::string y)
{
BOOST_ASSERT(x == y);
BOOST_TEST(x == y);
}
template<class P>
void f_impl(P const& p)
{
float v = p[value | 3.f];
BOOST_ASSERT(v == 3.f);
BOOST_TEST(v == 3.f);
assert_equal_string(p[name | "bar"], "foo");
}
@@ -70,7 +70,7 @@ namespace test
f_impl(args(a0, a1));
}
#ifndef BOOST_NO_SFINAE
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
@@ -96,10 +96,9 @@ int main()
f("foo", 3.f);
f(value = 3.f, name = "foo");
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
BOOST_TEST(f(3, 4) == 0);
#endif
return boost::report_errors();
}

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

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

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

View File

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

View File

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

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