Compare commits

..

34 Commits

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

[SVN r31672]
2005-11-15 20:50:59 +00:00
Daniel Wallin
3a5cabb94f Duplicate keyword arguments now disallowed. Based on contribution from
Daniel Earwicker.


[SVN r31671]
2005-11-15 20:50:58 +00:00
Daniel Wallin
5c79ce742c Added test for detecting duplicate keyword args.
[SVN r31670]
2005-11-15 20:45:54 +00:00
Dave Abrahams
863158c312 Workarounds for vc6
[SVN r31481]
2005-10-26 13:41:04 +00:00
Dave Abrahams
2518454e99 Make tutorial work with gcc-2.95.3
Make efficiency execute a number of repetitions determined by the
speed of the processor.


[SVN r31453]
2005-10-24 20:01:58 +00:00
Dave Abrahams
02735ebc2f Fixes for Borland
[SVN r31451]
2005-10-24 17:41:23 +00:00
Daniel Wallin
968a588eed Fix for SFINAE failure on VC7.1 when used with unnamed arguments.
[SVN r31380]
2005-10-18 23:13:52 +00:00
Dave Abrahams
d6b6b429be vc-7.1 warning suppression
[SVN r31378]
2005-10-18 19:55:11 +00:00
Daniel Wallin
10ce44d8cb Minor comment changes.
[SVN r31377]
2005-10-18 19:06:34 +00:00
Daniel Wallin
d78e0c8281 Fixed regression on GCC2.95.
[SVN r31376]
2005-10-18 18:29:45 +00:00
Dave Abrahams
1e7ca24606 initial commit
[SVN r31303]
2005-10-12 14:51:12 +00:00
Dave Abrahams
cf678265a6 Workarounds for vc6
[SVN r31293]
2005-10-11 22:02:28 +00:00
Dave Abrahams
6cf2dcbc84 Martin Wille pointed out some missing header dependencies; fixed.
Also moved boost/python/detail/is_xxx.hpp functionality into
boost/detail/is_xxx.hpp to decouple library dependencies between
python and parameter.


[SVN r31290]
2005-10-11 21:20:06 +00:00
Dave Abrahams
edd6439564 Martin Wille pointed out a missing anonymous namespace; fixed.
Changed Jamfile and Jamfile.v2 so that we'd build the efficiency test
in release mode always.


[SVN r31283]
2005-10-11 14:20:42 +00:00
Dave Abrahams
73eccfc901 added Stuart Dootson's results
[SVN r31027]
2005-09-19 02:29:23 +00:00
Dave Abrahams
4aa2996d75 Added a test result
[SVN r31017]
2005-09-18 00:46:08 +00:00
43 changed files with 7060 additions and 57 deletions

21
doc/Jamfile.v2 Executable file
View File

@@ -0,0 +1,21 @@
import docutils ;
import path ;
sources = [ path.glob . : *.rst ] ;
bases = $(sources:S=) ;
# This is a path relative to the html/ subdirectory where the
# generated output will eventually be moved.
stylesheet = "--stylesheet=rst.css" ;
for local b in $(bases)
{
html $(b) : $(b).rst :
#
<docutils-html>"-gdt --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
;
}
alias htmls : $(bases) ;
stage html : $(bases) ;

1189
doc/html/index.html Executable file

File diff suppressed because it is too large Load Diff

777
doc/html/reference.html Executable file
View File

@@ -0,0 +1,777 @@
<?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.3.8: http://docutils.sourceforge.net/" />
<title>The Boost Parameter Library Reference Documentation</title>
<link rel="stylesheet" href="rst.css" type="text/css" />
</head>
<body>
<div class="document" id="the-boost-parameter-library-reference-documentation">
<h1 class="title">The Boost Parameter Library Reference Documentation</h1>
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Daniel Wallin</td>
</tr>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:dalwan01&#64;student.umu.se">dalwan01&#64;student.umu.se</a></td>
</tr>
<tr class="field"><th class="field-name">organization:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date: 2005/07/17 19:53:01 $</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Daniel Wallin
2005. Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
</tr>
</tbody>
</table>
<hr class="docutils" />
<div class="contents topic" id="contents">
<p class="topic-title first"><a name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#preliminaries" id="id24" name="id24">1&nbsp;&nbsp;&nbsp;Preliminaries</a><ul class="auto-toc">
<li><a class="reference" href="#namespaces" id="id25" name="id25">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></li>
<li><a class="reference" href="#exceptions" id="id26" name="id26">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></li>
<li><a class="reference" href="#thread-safety" id="id27" name="id27">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></li>
<li><a class="reference" href="#typography" id="id28" name="id28">1.4&nbsp;&nbsp;&nbsp;Typography</a></li>
</ul>
</li>
<li><a class="reference" href="#terminology" id="id29" name="id29">2&nbsp;&nbsp;&nbsp;Terminology</a></li>
<li><a class="reference" href="#concepts" id="id30" name="id30">3&nbsp;&nbsp;&nbsp;Concepts</a><ul class="auto-toc">
<li><a class="reference" href="#argumentpack" id="id31" name="id31">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></li>
<li><a class="reference" href="#id5" id="id32" name="id32">3.2&nbsp;&nbsp;&nbsp;<span class="concept">ParameterSpec</span></a></li>
</ul>
</li>
<li><a class="reference" href="#class-templates" id="id33" name="id33">4&nbsp;&nbsp;&nbsp;Class Templates</a><ul class="auto-toc">
<li><a class="reference" href="#id7" id="id34" name="id34">4.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">keyword</span></tt></a></li>
<li><a class="reference" href="#parameters" id="id35" name="id35">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></li>
<li><a class="reference" href="#optional-required" id="id36" name="id36">4.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#metafunctions" id="id37" name="id37">5&nbsp;&nbsp;&nbsp;Metafunctions</a><ul class="auto-toc">
<li><a class="reference" href="#binding" id="id38" name="id38">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></li>
<li><a class="reference" href="#lazy-binding" id="id39" name="id39">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#code-generation-macros" id="id40" name="id40">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-fun-r-n-l-h-p" id="id41" name="id41">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-keyword-n-k" id="id42" name="id42">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></li>
<li><a class="reference" href="#boost-parameter-match-p-a-x" id="id43" name="id43">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#configuration-macros" id="id44" name="id44">7&nbsp;&nbsp;&nbsp;Configuration Macros</a><ul class="auto-toc">
<li><a class="reference" href="#boost-parameter-max-arity" id="id45" name="id45">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></li>
</ul>
</li>
<li><a class="reference" href="#tutorial" id="id46" name="id46">8&nbsp;&nbsp;&nbsp;Tutorial</a></li>
</ul>
</div>
<hr class="docutils" />
<div class="section" id="preliminaries">
<h1><a class="toc-backref" href="#id24" name="preliminaries">1&nbsp;&nbsp;&nbsp;Preliminaries</a></h1>
<p>This section covers some basic information you'll need to know in
order to understand this reference</p>
<div class="section" id="namespaces">
<h2><a class="toc-backref" href="#id25" name="namespaces">1.1&nbsp;&nbsp;&nbsp;Namespaces</a></h2>
<p>In this document, all unqualified identifiers should be assumed to
be defined in namespace <tt class="docutils literal"><span class="pre">boost::parameter</span></tt> unless otherwise
specified.</p>
</div>
<div class="section" id="exceptions">
<h2><a class="toc-backref" href="#id26" name="exceptions">1.2&nbsp;&nbsp;&nbsp;Exceptions</a></h2>
<p>No operation described in this document
throws an exception unless otherwise specified.</p>
</div>
<div class="section" id="thread-safety">
<h2><a class="toc-backref" href="#id27" name="thread-safety">1.3&nbsp;&nbsp;&nbsp;Thread Safety</a></h2>
<p>All components of this library can be used safely from multiple
threads without synchronization.<a class="footnote-reference" href="#thread" id="id2" name="id2"><sup>1</sup></a></p>
</div>
<div class="section" id="typography">
<h2><a class="toc-backref" href="#id28" name="typography">1.4&nbsp;&nbsp;&nbsp;Typography</a></h2>
<p>Names written in <span class="concept">sans serif type</span> represent <a class="reference" href="../../../../more/generic_programming.html#concept">concepts</a>.</p>
<p>In code blocks, <em>italic type</em> represents unspecified text that
satisfies the requirements given in the detailed description that
follows the code block.</p>
<p>In a specification of the tokens generated by a macro, <strong>bold
type</strong> is used to highlight the position of the expanded macro
argument in the result.</p>
<p>The special character β represents the value of <a class="reference" href="#boost-parameter-max-arity"><tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a>.</p>
</div>
</div>
<hr class="docutils" />
<div class="section" id="terminology">
<h1><a class="toc-backref" href="#id29" name="terminology">2&nbsp;&nbsp;&nbsp;Terminology</a></h1>
<span class="target" id="kw"></span><dl class="docutils">
<dt>keyword</dt>
<dd>The name of a function parameter.</dd>
</dl>
<span class="target" id="keyword-tag-type"></span><dl class="docutils">
<dt>keyword tag type</dt>
<dd>A type used to uniquely identify a function parameter. Typically
its name will be the same as that of the parameter.</dd>
</dl>
<span class="target" id="positional"></span><dl class="docutils">
<dt>positional argument</dt>
<dd>An argument passed with no explicit keyword. Its parameter is
determined in the usual C++ way: by position with respect to a
parameter list.</dd>
</dl>
<span class="target" id="tag-type"></span><dl class="docutils">
<dt>tag type</dt>
<dd>Shorthand for “<a class="reference" href="#keyword-tag-type">keyword tag type</a>.”</dd>
</dl>
<span class="target" id="keyword-object"></span><dl class="docutils">
<dt>keyword object</dt>
<dd>An instance of <a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a> <tt class="docutils literal"><span class="pre">&lt;T&gt;</span></tt> for some <a class="reference" href="#tag-type">tag type</a> <tt class="docutils literal"><span class="pre">T</span></tt>.</dd>
</dl>
<span class="target" id="tagged-reference"></span><dl class="docutils">
<dt>tagged reference</dt>
<dd><p class="first">An object whose type is associated with a <a class="reference" href="#keyword-tag-type">keyword tag type</a> (the
object's <em>keyword</em>), and that holds a reference (to the object's
<em>value</em>).</p>
<p class="last">As a shorthand, a “tagged reference to <tt class="docutils literal"><span class="pre">x</span></tt>” means a tagged
reference whose <em>value</em> is <tt class="docutils literal"><span class="pre">x</span></tt>.</p>
</dd>
</dl>
<span class="target" id="tagged-default"></span><dl class="docutils">
<dt>tagged default </dt>
<dd>A <a class="reference" href="#tagged-reference">tagged reference</a> whose <em>value</em> represents the value of a
default argument.</dd>
</dl>
<span class="target" id="tagged-lazy-default"></span><dl class="docutils">
<dt>tagged lazy default </dt>
<dd>A <a class="reference" href="#tagged-reference">tagged reference</a> whose <em>value</em>, when invoked with no
arguments, computes a default argument value.</dd>
</dl>
<span class="target" id="intended-argument-type"></span><dl class="docutils">
<dt>intended argument type</dt>
<dd>The <em>intended argument type</em> of a single-element <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> is the
type of its element's <em>value</em>. The intended argument type of any other
type <tt class="docutils literal"><span class="pre">X</span></tt> is <tt class="docutils literal"><span class="pre">X</span></tt> itself.</dd>
</dl>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">In this reference, we will use concept names (and other names)
to describe both types and objects, depending on context. So
for example, “an <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a>” can refer to a type that
models <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <em>or</em> an object of such a type.</p>
</div>
</div>
<hr class="docutils" />
<div class="section" id="concepts">
<h1><a class="toc-backref" href="#id30" name="concepts">3&nbsp;&nbsp;&nbsp;Concepts</a></h1>
<p>This section describes the generic type <a class="reference" href="../../../../more/generic_programming.html#concept">concepts</a> used by the Parameter library.</p>
<div class="section" id="argumentpack">
<h2><a class="toc-backref" href="#id31" name="argumentpack">3.1&nbsp;&nbsp;&nbsp;<span class="concept">ArgumentPack</span></a></h2>
<p>An <span class="concept">ArgumentPack</span> is a collection of <a class="reference" href="#tagged-reference">tagged reference</a>s to the
actual arguments passed to a function. Every <span class="concept">ArgumentPack</span> is
also a valid MPL <a class="reference" href="../../../mpl/doc/refmanual/forward-sequence.html"><span class="concept">Forward Sequence</span></a> consisting of the <a class="reference" href="#keyword-tag-type">keyword tag type</a>s in its <a class="reference" href="#tagged-reference">tagged reference</a>s.</p>
<div class="section" id="requirements">
<h3><a name="requirements">Requirements</a></h3>
<p>In the table below,</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <span class="concept">ArgumentPack</span></li>
<li><tt class="docutils literal"><span class="pre">x</span></tt> is an instance of <tt class="docutils literal"><span class="pre">A</span></tt></li>
<li><tt class="docutils literal"><span class="pre">u</span></tt> is a <a class="reference" href="#keyword-object">keyword object</a> of type <tt class="docutils literal"><span class="pre">K</span></tt></li>
<li><tt class="docutils literal"><span class="pre">v</span></tt> is a <a class="reference" href="#tagged-default">tagged default</a> with <a class="reference" href="#tag-type">tag type</a> <tt class="docutils literal"><span class="pre">L</span></tt> and <em>value</em> of type <tt class="docutils literal"><span class="pre">D</span></tt></li>
<li><tt class="docutils literal"><span class="pre">w</span></tt> is a <a class="reference" href="#tagged-lazy-default">tagged lazy default</a> with <a class="reference" href="#tag-type">tag type</a> <tt class="docutils literal"><span class="pre">M</span></tt> and <em>value</em> of type <tt class="docutils literal"><span class="pre">E</span> <span class="pre">const</span></tt></li>
<li><tt class="docutils literal"><span class="pre">z</span></tt> is an <span class="concept">ArgumentPack</span> containing a single element (as created by <a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a><tt class="docutils literal"><span class="pre">&lt;&gt;::operator=</span></tt>)</li>
</ul>
<p>Any exceptions are thrown from the invocation of <tt class="docutils literal"><span class="pre">w</span></tt>'s <em>value</em>
will be propagated to the caller.</p>
<table border="1" class="docutils">
<caption><span class="concept">ArgumentPack</span> requirements</caption>
<colgroup>
<col width="11%" />
<col width="31%" />
<col width="19%" />
<col width="40%" />
</colgroup>
<thead valign="bottom">
<tr><th>Expression</th>
<th>Type</th>
<th>Requirements</th>
<th>Semantics/Notes</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">x[u]</span></tt></td>
<td><tt class="docutils literal"><span class="pre">binding&lt;A,K&gt;::type</span></tt></td>
<td><tt class="docutils literal"><span class="pre">x</span></tt> contains an
element <em>b</em> whose
<a class="reference" href="#kw">keyword</a> is <tt class="docutils literal"><span class="pre">K</span></tt></td>
<td>Returns <em>b</em>'s <em>value</em> (by
reference).</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">x[u]</span></tt></td>
<td><tt class="docutils literal"><span class="pre">binding&lt;A,L,D&gt;::type</span></tt></td>
<td><em>none</em></td>
<td>If <tt class="docutils literal"><span class="pre">x</span></tt> contains an element <em>b</em> whose
<a class="reference" href="#kw">keyword</a> is the same as <tt class="docutils literal"><span class="pre">u</span></tt>'s,
returns <em>b</em>'s <em>value</em> (by
reference). Otherwise, returns <tt class="docutils literal"><span class="pre">u</span></tt>'s <em>value</em>.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">x[w]</span></tt></td>
<td><tt class="docutils literal"><span class="pre">lazy_binding&lt;A,M,E&gt;::type</span></tt></td>
<td><em>none</em></td>
<td>If <tt class="docutils literal"><span class="pre">x</span></tt> contains an element <em>b</em> whose
<a class="reference" href="#kw">keyword</a> is the same as <tt class="docutils literal"><span class="pre">w</span></tt>'s,
returns <em>b</em>'s <em>value</em> (by
reference). Otherwise, invokes <tt class="docutils literal"><span class="pre">w</span></tt>'s <em>value</em> and returns the result.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">x,</span> <span class="pre">z</span></tt></td>
<td>Model of <span class="concept">ArgumentPack</span></td>
<td><em>none</em></td>
<td>Returns an <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> containing
all the elements of both <tt class="docutils literal"><span class="pre">x</span></tt> and
<tt class="docutils literal"><span class="pre">z</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="id5">
<h2><a class="toc-backref" href="#id32" name="id5">3.2&nbsp;&nbsp;&nbsp;<span class="target" id="parameterspec"></span><span class="concept">ParameterSpec</span></a></h2>
<p>A <span class="concept">ParameterSpec</span> describes the type requirements for arguments
corresponding to a given <a class="reference" href="#kw">keyword</a> and indicates whether the argument
is optional or required. The table below details the allowed forms
and describes their condition for satisfaction by an actual
argument type. In each row,</p>
<span class="target" id="conditions"></span><ul class="simple">
<li><tt class="docutils literal"><span class="pre">K</span></tt> is the <span class="concept">ParameterSpec</span>'s <a class="reference" href="#keyword-tag-type">keyword tag type</a></li>
<li><tt class="docutils literal"><span class="pre">A</span></tt> is an <a class="reference" href="#intended-argument-type">intended argument type</a> associated with <tt class="docutils literal"><span class="pre">K</span></tt>, if any</li>
<li><tt class="docutils literal"><span class="pre">F</span></tt> is a unary <a class="reference" href="../../../mpl/doc/refmanual/lambda-expression.html">MPL lambda expression</a></li>
</ul>
<table border="1" class="docutils">
<caption><span class="concept">ParameterSpec</span> allowed forms and conditions of satisfaction</caption>
<colgroup>
<col width="32%" />
<col width="21%" />
<col width="47%" />
</colgroup>
<thead valign="bottom">
<tr><th>Type</th>
<th><tt class="docutils literal"><span class="pre">A</span></tt> required</th>
<th>Condition <tt class="docutils literal"><span class="pre">A</span></tt> must satisfy</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a><tt class="docutils literal"><span class="pre">&lt;K&gt;</span></tt></td>
<td>no</td>
<td><em>n/a</em></td>
</tr>
<tr><td><a class="reference" href="#optional"><tt class="docutils literal"><span class="pre">optional</span></tt></a><tt class="docutils literal"><span class="pre">&lt;K,F&gt;</span></tt></td>
<td>no</td>
<td><tt class="docutils literal"><span class="pre">mpl::apply&lt;F,A&gt;::type::value</span></tt>
is <tt class="docutils literal"><span class="pre">true</span></tt>.</td>
</tr>
<tr><td><a class="reference" href="#required"><tt class="docutils literal"><span class="pre">required</span></tt></a><tt class="docutils literal"><span class="pre">&lt;K,F&gt;</span></tt></td>
<td>yes</td>
<td><tt class="docutils literal"><span class="pre">mpl::apply&lt;F,A&gt;::type::value</span></tt>
is <tt class="docutils literal"><span class="pre">true</span></tt>.</td>
</tr>
</tbody>
</table>
<p>The information in a <span class="concept">ParameterSpec</span> is used to <a class="reference" href="index.html#controlling-overload-resolution">limit</a> the
arguments that will be matched by <a class="reference" href="index.html#forwarding-functions">forwarding functions</a>.</p>
</div>
</div>
<hr class="docutils" />
<div class="section" id="class-templates">
<h1><a class="toc-backref" href="#id33" name="class-templates">4&nbsp;&nbsp;&nbsp;Class Templates</a></h1>
<div class="section" id="id7">
<h2><a class="toc-backref" href="#id34" name="id7">4.1&nbsp;&nbsp;&nbsp;<span class="target" id="keyword"></span><tt class="docutils literal"><span class="pre">keyword</span></tt></a></h2>
<p>The type of every <a class="reference" href="#keyword-object">keyword object</a> is a specialization of <tt class="docutils literal"><span class="pre">keyword</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/keyword.hpp">boost/parameter/keyword.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class Tag&gt;
struct keyword
{
template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#operator">operator=</a>(T&amp; value) const;
template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#operator">operator=</a>(T const&amp; value) const;
template &lt;class T&gt; <em>tagged default</em> <a class="reference" href="#id9">operator|</a>(T&amp; x) const;
template &lt;class T&gt; <em>tagged default</em> <a class="reference" href="#id9">operator|</a>(T const&amp; x) const;
template &lt;class F&gt; <em>tagged lazy default</em> <a class="reference" href="#id10">operator||</a>(F const&amp;) const;
static keyword&lt;Tag&gt;&amp; <a class="reference" href="#get">get</a>();
};
</pre>
<span class="target" id="operator"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">operator=</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> operator=(T&amp; value) const;
template &lt;class T&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> operator=(T const&amp; value) const;
</pre>
<table class="last docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body">nothing</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">an <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> containing a single <a class="reference" href="#tagged-reference">tagged reference</a> to
<tt class="docutils literal"><span class="pre">value</span></tt> with <a class="reference" href="#kw">keyword</a> <tt class="docutils literal"><span class="pre">Tag</span></tt></td>
</tr>
</tbody>
</table>
</dd>
</dl>
<span class="target" id="id9"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">operator|</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class T&gt; <em>tagged default</em> operator|(T&amp; x) const;
template &lt;class T&gt; <em>tagged default</em> operator|(T const&amp; x) const;
</pre>
<table class="last docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <a class="reference" href="#tagged-default">tagged default</a> with <em>value</em> <tt class="docutils literal"><span class="pre">x</span></tt> and <a class="reference" href="#kw">keyword</a> <tt class="docutils literal"><span class="pre">Tag</span></tt>.</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<span class="target" id="id10"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">operator||</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class F&gt; <em>tagged lazy default</em> operator||(F const&amp; g) const;
</pre>
<table class="last docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">g()</span></tt> is valid, with type <tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt>.<a class="footnote-reference" href="#no-result-of" id="id11" name="id11"><sup>2</sup></a></td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <a class="reference" href="#tagged-lazy-default">tagged lazy default</a> with <em>value</em> <tt class="docutils literal"><span class="pre">g</span></tt> and <a class="reference" href="#kw">keyword</a> <tt class="docutils literal"><span class="pre">Tag</span></tt>.</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<span class="target" id="get"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">get</span></tt></dt>
<dd><pre class="first literal-block">
static keyword&lt;Tag&gt;&amp; get();
</pre>
<table class="last docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a “singleton instance”: the same object will be
returned on each invocation of <tt class="docutils literal"><span class="pre">get()</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Thread Safety:</th><td class="field-body"><tt class="docutils literal"><span class="pre">get()</span></tt> can be called from multiple threads
simultaneously.</td>
</tr>
</tbody>
</table>
</dd>
</dl>
</div>
<div class="section" id="parameters">
<h2><a class="toc-backref" href="#id35" name="parameters">4.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">parameters</span></tt></a></h2>
<p>Provides an interface for assembling the actual arguments to a
<cite>forwarding function</cite> into an <span class="concept">ArgumentPack</span>, in which any
<a class="reference" href="#positional">positional</a> arguments will be tagged according to the
corresponding template argument to <tt class="docutils literal"><span class="pre">parameters</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/parameters.hpp">boost/parameter/parameters.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class P0 = <em>unspecified</em>, class P1 = <em>unspecified</em>, …class Pβ = <em>unspecified</em>&gt;
struct parameters
{
template &lt;class A0, class A1 = <em>unspecified</em>, …class Aβ = <em>unspecified</em>&gt;
struct <a class="reference" href="#match">match</a>
{
typedef … type;
};
template &lt;class A0&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0) const;
template &lt;class A0, class A1&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, A1 const&amp; a1) const;
<span class="doublesize"></span>
template &lt;class A0, class A1, …class Aβ&gt;
<a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, A1 const&amp; a1, …Aβ const&amp; aβ) const;
};
</pre>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">P0</span></tt>, <tt class="docutils literal"><span class="pre">P1</span></tt>, … <tt class="docutils literal"><span class="pre">P</span></tt>β are models of <a class="reference" href="#parameterspec"><span class="concept">ParameterSpec</span></a>.</td>
</tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p>In this section, <tt class="docutils literal"><span class="pre">R</span></tt><em>i</em> and <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> are defined as
follows, for any argument type <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em>:</p>
<blockquote class="last">
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">R</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em>'s <a class="reference" href="#intended-argument-type">intended argument type</a></div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">if <tt class="docutils literal"><span class="pre">A</span></tt><em>i</em> is a result type of <tt class="docutils literal"><span class="pre">keyword&lt;T&gt;::</span></tt><a class="reference" href="#operator"><tt class="docutils literal"><span class="pre">operator=</span></tt></a></div>
<div class="line">then </div>
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">T</span></tt></div>
</div>
<div class="line">else </div>
<div class="line-block">
<div class="line"><tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> is <tt class="docutils literal"><span class="pre">P</span></tt><em>i</em>'s <a class="reference" href="#keyword-tag-type">keyword tag type</a>.</div>
</div>
</div>
</div>
</blockquote>
</div>
<span class="target" id="match"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">match</span></tt></dt>
<dd><p class="first">A <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> used to remove a <a class="reference" href="index.html#forwarding-functions">forwarding function</a> from overload resolution.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">if <tt class="docutils literal"><span class="pre">P0</span></tt>, <tt class="docutils literal"><span class="pre">P1</span></tt>, …<tt class="docutils literal"><span class="pre">P</span></tt>β are <em>satisfied</em> (see
below), then <tt class="docutils literal"><span class="pre">parameters&lt;P0,P1,…Pβ&gt;</span></tt>. Otherwise,
<tt class="docutils literal"><span class="pre">match&lt;A0,A1,…Aβ&gt;::type</span></tt> is not defined.</td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal"><span class="pre">P0</span></tt>, <tt class="docutils literal"><span class="pre">P1</span></tt>, …<tt class="docutils literal"><span class="pre">P</span></tt>β are <strong>satisfied</strong> if, for
every <em>j</em> in 0…β, either:</p>
<ul class="last simple">
<li><tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is the <em>unspecified</em> default</li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is a specialization of <a class="reference" href="#keyword"><tt class="docutils literal"><span class="pre">keyword</span></tt></a>,</li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is <a class="reference" href="#optional"><tt class="docutils literal"><span class="pre">optional</span></tt></a> <tt class="docutils literal"><span class="pre">&lt;X,F&gt;</span></tt> and either<ul>
<li><tt class="docutils literal"><span class="pre">X</span></tt> is not <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> for any <em>i</em>,</li>
<li><strong>or</strong> <tt class="docutils literal"><span class="pre">X</span></tt> is some <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> and <tt class="docutils literal"><span class="pre">mpl::apply&lt;F,R</span></tt><em>i</em><tt class="docutils literal"><span class="pre">&gt;::type::value</span></tt> is <tt class="docutils literal"><span class="pre">true</span></tt></li>
</ul>
</li>
<li><strong>or</strong>, <tt class="docutils literal"><span class="pre">P</span></tt><em>j</em> is <a class="reference" href="#required"><tt class="docutils literal"><span class="pre">required</span></tt></a> <tt class="docutils literal"><span class="pre">&lt;X,F&gt;</span></tt>, and<ul>
<li><tt class="docutils literal"><span class="pre">X</span></tt> is some <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em>, <strong>and</strong></li>
<li><tt class="docutils literal"><span class="pre">mpl::apply&lt;F,R</span></tt><em>i</em><tt class="docutils literal"><span class="pre">&gt;::type::value</span></tt> is <tt class="docutils literal"><span class="pre">true</span></tt></li>
</ul>
</li>
</ul>
</dd>
</dl>
<span class="target" id="id13"></span><dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">operator()</span></tt></dt>
<dd><pre class="first literal-block">
template &lt;class A0&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> operator()(A0 const&amp; a0) const;
<span class="doublesize"></span>
template &lt;class A0, …class Aβ&gt; <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> <a class="reference" href="#id13">operator()</a>(A0 const&amp; a0, …Aβ const&amp; aβ) const;
</pre>
<table class="last docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">An <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a> containing, for each <tt class="docutils literal"><span class="pre">a</span></tt><em>i</em>,</p>
<ul class="last simple">
<li>if <tt class="docutils literal"><span class="pre">a</span></tt><em>i</em>, is a single-element <span class="concept">ArgumentPack</span>, its element</li>
<li>Otherwise, a <a class="reference" href="#tagged-reference">tagged reference</a> with <a class="reference" href="#kw">keyword</a> <tt class="docutils literal"><span class="pre">K</span></tt><em>i</em> and <em>value</em> <tt class="docutils literal"><span class="pre">a</span></tt><em>i</em></li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
</div>
<div class="section" id="optional-required">
<h2><a class="toc-backref" href="#id36" name="optional-required">4.3&nbsp;&nbsp;&nbsp;<span class="target" id="required"></span><span class="target" id="optional"></span><tt class="docutils literal"><span class="pre">optional</span></tt>, <tt class="docutils literal"><span class="pre">required</span></tt></a></h2>
<p>These templates describe the requirements on a function parameter.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/parameters.hpp">boost/parameter/parameters.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name" colspan="2">Specializations model:</th></tr>
<tr><td>&nbsp;</td><td class="field-body"><a class="reference" href="#parameterspec"><span class="concept">ParameterSpec</span></a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class Tag, class Predicate = <em>unspecified</em>&gt;
struct optional;
template &lt;class Tag, class Predicate = <em>unspecified</em>&gt;
struct required;
</pre>
<p>The default value of <tt class="docutils literal"><span class="pre">Predicate</span></tt> is an unspecified <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> that returns
<tt class="docutils literal"><span class="pre">mpl::true_</span></tt> for any argument.</p>
</div>
</div>
<hr class="docutils" />
<div class="section" id="metafunctions">
<h1><a class="toc-backref" href="#id37" name="metafunctions">5&nbsp;&nbsp;&nbsp;Metafunctions</a></h1>
<p>A <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> is conceptually a function that operates on, and
returns, C++ types.</p>
<div class="section" id="binding">
<h2><a class="toc-backref" href="#id38" name="binding">5.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">binding</span></tt></a></h2>
<p>Returns the result type of indexing an argument pack with a
<a class="reference" href="#keyword-tag-type">keyword tag type</a> or with a <a class="reference" href="#tagged-default">tagged default</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined n:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/binding.hpp">boost/parameter/binding.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class A, class K, class D = void&gt;
struct binding
{
typedef … type;
};
</pre>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the reference type of the <a class="reference" href="#tagged-reference">tagged reference</a> in <tt class="docutils literal"><span class="pre">A</span></tt>
having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt class="docutils literal"><span class="pre">K</span></tt>, if any. If no such <a class="reference" href="#tagged-reference">tagged reference</a> exists, returns <tt class="docutils literal"><span class="pre">D</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="lazy-binding">
<h2><a class="toc-backref" href="#id39" name="lazy-binding">5.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">lazy_binding</span></tt></a></h2>
<p>Returns the result type of indexing an argument pack with a <a class="reference" href="#tagged-lazy-default">tagged lazy default</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/binding.hpp">boost/parameter/binding.hpp</a></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class A, class K, class F&gt;
struct lazy_binding
{
typedef … type;
};
</pre>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">A</span></tt> is a model of <a class="reference" href="#argumentpack"><span class="concept">ArgumentPack</span></a>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the reference type of the <a class="reference" href="#tagged-reference">tagged reference</a> in <tt class="docutils literal"><span class="pre">A</span></tt>
having <a class="reference" href="#keyword-tag-type">keyword tag type</a> <tt class="docutils literal"><span class="pre">K</span></tt>, if any. If no such <a class="reference" href="#tagged-reference">tagged reference</a> exists, returns <tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt>.<a class="footnote-reference" href="#no-result-of" id="id17" name="id17"><sup>2</sup></a></td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="docutils" />
<div class="section" id="code-generation-macros">
<h1><a class="toc-backref" href="#id40" name="code-generation-macros">6&nbsp;&nbsp;&nbsp;Code Generation Macros</a></h1>
<p>Macros in this section can be used to ease the writing of code
using the Parameter libray by eliminating repetitive boilerplate.</p>
<div class="section" id="boost-parameter-fun-r-n-l-h-p">
<h2><a class="toc-backref" href="#id41" name="boost-parameter-fun-r-n-l-h-p">6.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN(r,n,l,h,p)</span></tt></a></h2>
<p>Generates a sequence of <a class="reference" href="index.html#forwarding-functions">forwarding function</a> templates named
<tt class="docutils literal"><span class="pre">n</span></tt>, with arities ranging from <tt class="docutils literal"><span class="pre">l</span></tt> to <tt class="docutils literal"><span class="pre">h</span></tt> , returning <tt class="docutils literal"><span class="pre">r</span></tt>,
and using <tt class="docutils literal"><span class="pre">p</span></tt> to control overload resolution and assign tags to
positional arguments.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/macros.hpp">boost/parameter/macros.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">l</span></tt> and <tt class="docutils literal"><span class="pre">h</span></tt> are nonnegative integer tokens such
that <tt class="docutils literal"><span class="pre">l</span></tt> &lt; <tt class="docutils literal"><span class="pre">h</span></tt></td>
</tr>
</tbody>
</table>
<dl class="docutils">
<dt>Generates</dt>
<dd><pre class="first last literal-block">
template &lt;class A1, class A2, …class A##<strong>l</strong>&gt;
r name(
A1 const&amp; a1, A2 const&amp; a2, …A<strong>l</strong> const&amp; x<strong>l</strong>
, typename <strong>p</strong>::match&lt;A1,A2,…A<strong>l</strong>&gt;::type p = <strong>p</strong>())
{
return <strong>name</strong>_with_named_params(<strong>p</strong>(x1,x2,…x<strong>l</strong>));
}
template &lt;class A1, class A2, …class A<strong>l</strong>, class A##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)&gt;
r name(
A1 const&amp; a1, A2 const&amp; a2, …A<strong>l</strong> const&amp; x<strong>l</strong>
, A##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>) const&amp; x##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)
, typename <strong>p</strong>::match&lt;A1,A2,…A<strong>l</strong>,A##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)&gt;::type p = <strong>p</strong>())
{
return <strong>name</strong>_with_named_params(<strong>p</strong>(x1,x2,…x<strong>l</strong>,x##<a class="reference" href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC</a>(<strong>l</strong>)));
}
<span class="doublesize"></span>
template &lt;class A1, class A2, …class A<strong>h</strong>&gt;
r name(
A1 const&amp; a1, A2 const&amp; a2, …A<strong>h</strong> const&amp; x<strong>h</strong>
, typename <strong>p</strong>::match&lt;A1,A2,…A<strong>h</strong>&gt;::type p = <strong>p</strong>())
{
return <strong>name</strong>_with_named_params(<strong>p</strong>(a1,a2,…a<strong>h</strong>));
}
</pre>
</dd>
</dl>
</div>
<div class="section" id="boost-parameter-keyword-n-k">
<h2><a class="toc-backref" href="#id42" name="boost-parameter-keyword-n-k">6.2&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_KEYWORD(n,k)</span></tt></a></h2>
<p>Generates the declaration of a <a class="reference" href="#keyword-tag-type">keyword tag type</a> named <tt class="docutils literal"><span class="pre">k</span></tt> in
namespace <tt class="docutils literal"><span class="pre">n</span></tt>, and a corresponding <a class="reference" href="#keyword-object">keyword object</a> definition in
the enclosing namespace.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/keyword.hpp">boost/parameter/keyword.hpp</a></td>
</tr>
</tbody>
</table>
<dl class="docutils">
<dt>Generates</dt>
<dd><pre class="first last literal-block">
namespace <strong>n</strong> { struct <strong>k</strong>; }
namespace {
boost::parameter::keyword&lt;<em>tag-namespace</em>::<strong>k</strong>&gt;&amp; <strong>k</strong>
= boost::parameter::keyword&lt;<em>tag-namespace</em>::<strong>k</strong>&gt;::get();
}
</pre>
</dd>
</dl>
</div>
<div class="section" id="boost-parameter-match-p-a-x">
<h2><a class="toc-backref" href="#id43" name="boost-parameter-match-p-a-x">6.3&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH(p,a,x)</span></tt></a></h2>
<p>Generates a defaulted parameter declaration for a <a class="reference" href="index.html#forwarding-functions">forwarding
function</a>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/match.hpp">boost/parameter/match.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><p class="first"><tt class="docutils literal"><span class="pre">a</span></tt> is a <a class="reference" href="http://www.boost.org/libs/preprocessor/doc/data.html">Boost.Preprocessor sequence</a>
of the form</p>
<pre class="last literal-block">
(A0)(A1)…(A<em>n</em>)
</pre>
</td>
</tr>
</tbody>
</table>
<dl class="docutils">
<dt>Generates</dt>
<dd><pre class="first last literal-block">
typename <strong>p</strong>::match&lt;<strong>A0</strong>,<strong>A1</strong>…,<strong>A</strong><em>n</em>&gt;::type <strong>x</strong> = <strong>p</strong>()
</pre>
</dd>
</dl>
</div>
</div>
<div class="section" id="configuration-macros">
<h1><a class="toc-backref" href="#id44" name="configuration-macros">7&nbsp;&nbsp;&nbsp;Configuration Macros</a></h1>
<div class="section" id="boost-parameter-max-arity">
<h2><a class="toc-backref" href="#id45" name="boost-parameter-max-arity">7.1&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt></a></h2>
<p>Determines the maximum number of arguments supported by the
library. Will only be <tt class="docutils literal"><span class="pre">#defined</span></tt> by the library if it is not
already <tt class="docutils literal"><span class="pre">#defined</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Defined in:</th><td class="field-body"><a class="reference" href="../../../../boost/parameter/config.hpp">boost/parameter/config.hpp</a></td>
</tr>
</tbody>
</table>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Default Value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">5</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="tutorial">
<h1><a class="toc-backref" href="#id46" name="tutorial">8&nbsp;&nbsp;&nbsp;Tutorial</a></h1>
<p>Follow <a class="reference" href="index.html#tutorial">this link</a> to the Boost.Parameter tutorial
documentation.</p>
<hr class="docutils" />
<table class="docutils footnote" frame="void" id="thread" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2" name="thread">[1]</a></td><td>References to tag objects may be initialized multiple
times. This scenario can only occur in the presence of
threading. Because the C++ standard doesn't consider threading,
it doesn't explicitly allow or forbid multiple initialization of
references. That said, it's hard to imagine an implementation
where it could make a difference.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="no-result-of" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="no-result-of">[2]</a></td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id17">2</a>)</em> Where <a class="reference" href="../../../utility/utility.htm#BOOST_NO_RESULT_OF"><tt class="docutils literal"><span class="pre">BOOST_NO_RESULT_OF</span></tt></a> is <tt class="docutils literal"><span class="pre">#defined</span></tt>,
<tt class="docutils literal"><span class="pre">boost::</span></tt><a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a><tt class="docutils literal"><span class="pre">&lt;F()&gt;::type</span></tt> is replaced by
<tt class="docutils literal"><span class="pre">F::result_type</span></tt>.</td></tr>
</tbody>
</table>
</div>
</div>
<hr class="docutils footer" />
<div class="footer">
Generated on: 2006-01-27 01:56 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

28
doc/html/rst.css Executable file
View File

@@ -0,0 +1,28 @@
@import "../../../../rst.css";
div.section div.section div.section dl {
margin-left: 2em;
}
td span {
vertical-align: text-top;
}
img {
border: none;
vertical-align: middle
}
PRE
{
FONT-FAMILY: monospace ;
}
CODE
{
FONT-FAMILY: monospace;
}
.pre
{
FONT-FAMILY: monospace;
}

1266
doc/index.rst Executable file

File diff suppressed because it is too large Load Diff

686
doc/reference.rst Executable file
View File

@@ -0,0 +1,686 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The Boost Parameter Library Reference Documentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|(logo)|__
.. |(logo)| image:: ../../../../boost.png
:alt: Boost
__ ../../../../index.htm
:Authors: David Abrahams, Daniel Wallin
:Contact: dave@boost-consulting.com, dalwan01@student.umu.se
:organization: `Boost Consulting`_
: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
//////////////////////////////////////////////////////////////////////////////
.. contents::
:depth: 2
//////////////////////////////////////////////////////////////////////////////
.. role:: class
:class: class
.. role:: concept
:class: concept
.. role:: function
:class: function
.. |ArgumentPack| replace:: :concept:`ArgumentPack`
.. |ForwardSequence| replace:: :concept:`Forward Sequence`
.. |ParameterSpec| replace:: :concept:`ParameterSpec`
.. role:: large
:class: doublesize
.. section-numbering::
:depth: 2
Preliminaries
=============
This section covers some basic information you'll need to know in
order to understand this reference
Namespaces
----------
In this document, all unqualified identifiers should be assumed to
be defined in namespace ``boost::parameter`` unless otherwise
specified.
Exceptions
----------
No operation described in this document
throws an exception unless otherwise specified.
Thread Safety
-------------
All components of this library can be used safely from multiple
threads without synchronization. [#thread]_
Typography
----------
Names written in :concept:`sans serif type` represent concepts_.
In code blocks, *italic type* represents unspecified text that
satisfies the requirements given in the detailed description that
follows the code block.
In a specification of the tokens generated by a macro, **bold
type** is used to highlight the position of the expanded macro
argument in the result.
The special character β represents the value of |BOOST_PARAMETER_MAX_ARITY|_.
//////////////////////////////////////////////////////////////////////////////
Terminology
===========
.. |kw| replace:: keyword
.. _kw:
keyword
The name of a function parameter.
.. _keyword tag type:
.. |keyword tag type| replace:: `keyword tag type`_
keyword tag type
A type used to uniquely identify a function parameter. Typically
its name will be the same as that of the parameter.
.. _positional:
.. |positional| replace:: `positional`_
positional argument
An argument passed with no explicit |kw|. Its parameter is
determined in the usual C++ way: by position with respect to a
parameter list.
.. _tag type:
.. |tag type| replace:: `tag type`_
tag type
Shorthand for “\ |keyword tag type|.”
.. _keyword object:
.. |keyword object| replace:: `keyword object`_
keyword object
An instance of |keyword|_ ``<T>`` for some |tag
type| ``T``.
.. _tagged reference:
.. |tagged reference| replace:: `tagged reference`_
tagged reference
An object whose type is associated with a |keyword tag type| (the
object's *keyword*), and that holds a reference (to the object's
*value*).
As a shorthand, a “tagged reference to ``x``\ ” means a tagged
reference whose *value* is ``x``.
.. _tagged default:
.. |tagged default| replace:: `tagged default`_
tagged default
A |tagged reference| whose *value* represents the value of a
default argument.
.. _tagged lazy default:
.. |tagged lazy default| replace:: `tagged lazy default`_
tagged lazy default
A |tagged reference| whose *value*, when invoked with no
arguments, computes a default argument value.
.. _intended argument type:
.. |intended argument type| replace:: `intended argument type`_
intended argument type
The *intended argument type* of a single-element |ArgumentPack|_ is the
type of its element's *value*. The intended argument type of any other
type ``X`` is ``X`` itself.
.. Note::
In this reference, we will use concept names (and other names)
to describe both types and objects, depending on context. So
for example, “an |ArgumentPack|_\ ” can refer to a type that
models |ArgumentPack|_ *or* an object of such a type.
//////////////////////////////////////////////////////////////////////////////
Concepts
========
This section describes the generic type concepts_ used by the Parameter library.
.. _concepts: ../../../../more/generic_programming.html#concept
|ArgumentPack|
--------------
An |ArgumentPack| is a collection of |tagged reference|\ s to the
actual arguments passed to a function. Every |ArgumentPack| is
also a valid MPL |ForwardSequence|__ consisting of the |keyword tag
type|\ s in its |tagged reference|\ s.
__ ../../../mpl/doc/refmanual/forward-sequence.html
Requirements
............
In the table below,
* ``A`` is a model of |ArgumentPack|
* ``x`` is an instance of ``A``
* ``u`` is a |keyword object| of type ``K``
* ``v`` is a |tagged default| with |tag type| ``L`` and *value* of type ``D``
* ``w`` is a |tagged lazy default| with |tag type| ``M`` and *value* of type ``E const``
* ``z`` is an |ArgumentPack| containing a single element (as created by |keyword|_\ ``<…>::operator=``)
Any exceptions are thrown from the invocation of ``w``\ 's *value*
will be propagated to the caller.
.. table:: |ArgumentPack| requirements
+----------+-----------------------------+------------------+--------------------------------------+
|Expression| Type |Requirements |Semantics/Notes |
+==========+=============================+==================+======================================+
|``x[u]`` |``binding<A,K>::type`` |``x`` contains an |Returns *b*\ 's *value* (by |
| | |element *b* whose |reference). |
| | ||kw|_ is ``K`` | |
+----------+-----------------------------+------------------+--------------------------------------+
|``x[u]`` |``binding<A,L,D>::type`` |*none* |If ``x`` contains an element *b* whose|
| | | ||kw|_ is the same as ``u``\ 's, |
| | | |returns *b*\ 's *value* (by |
| | | |reference). Otherwise, returns ``u``\|
| | | |'s *value*. |
+----------+-----------------------------+------------------+--------------------------------------+
|``x[w]`` |``lazy_binding<A,M,E>::type``|*none* |If ``x`` contains an element *b* whose|
| | | ||kw|_ is the same as ``w``\ 's, |
| | | |returns *b*\ 's *value* (by |
| | | |reference). Otherwise, invokes ``w``\|
| | | |'s *value* and returns the result. |
+----------+-----------------------------+------------------+--------------------------------------+
|``x, z`` |Model of |ArgumentPack| |*none* |Returns an |ArgumentPack|_ containing |
| | | |all the elements of both ``x`` and |
| | | |``z``. |
+----------+-----------------------------+------------------+--------------------------------------+
.. _parameterspec:
|ParameterSpec|
---------------
A |ParameterSpec| describes the type requirements for arguments
corresponding to a given |kw|_ and indicates whether the argument
is optional or required. The table below details the allowed forms
and describes their condition for satisfaction by an actual
argument type. In each row,
.. _conditions:
* ``K`` is the |ParameterSpec|\ 's |keyword tag type|
* ``A`` is an |intended argument type| associated with ``K``, if any
* ``F`` is a unary `MPL lambda expression`_
.. _`MPL lambda expression`: ../../../mpl/doc/refmanual/lambda-expression.html
.. table:: |ParameterSpec| allowed forms and conditions of satisfaction
+----------------------+--------------+--------------------------------+
|Type |``A`` required|Condition ``A`` must satisfy |
+======================+==============+================================+
||keyword|_\ ``<K>`` |no |*n/a* |
+----------------------+--------------+--------------------------------+
||optional|_\ ``<K,F>``|no |``mpl::apply<F,A>::type::value``|
| | |is ``true``. |
+----------------------+--------------+--------------------------------+
||required|_\ ``<K,F>``|yes |``mpl::apply<F,A>::type::value``|
| | |is ``true``. |
+----------------------+--------------+--------------------------------+
The information in a |ParameterSpec| is used to `limit`__ the
arguments that will be matched by `forwarding functions`_.
__ overloadcontrol_
.. _overloadcontrol: index.html#controlling-overload-resolution
.. _forwarding functions: index.html#forwarding-functions
//////////////////////////////////////////////////////////////////////////////
Class Templates
===============
.. |keyword| replace:: ``keyword``
.. _keyword:
``keyword``
-----------
The type of every |keyword object| is a specialization of |keyword|.
:Defined in: `boost/parameter/keyword.hpp`__
__ ../../../../boost/parameter/keyword.hpp
.. parsed-literal::
template <class Tag>
struct keyword
{
template <class T> |ArgumentPack|_ `operator=`_\(T& value) const;
template <class T> |ArgumentPack|_ `operator=`_\(T const& value) const;
template <class T> *tagged default* `operator|`_\(T& x) const;
template <class T> *tagged default* `operator|`_\(T const& x) const;
template <class F> *tagged lazy default* `operator||`_\(F const&) const;
static keyword<Tag>& get_\();
};
.. |operator=| replace:: ``operator=``
.. _operator=:
``operator=``
.. parsed-literal::
template <class T> |ArgumentPack|_ operator=(T& value) const;
template <class T> |ArgumentPack|_ operator=(T const& value) const;
:Requires: nothing
:Returns:
an |ArgumentPack|_ containing a single |tagged reference| to
``value`` with |kw|_ ``Tag``
.. _operator|:
``operator|``
.. parsed-literal::
template <class T> *tagged default* operator|(T& x) const;
template <class T> *tagged default* operator|(T const& x) const;
:Returns: a |tagged default| with *value* ``x`` and |kw|_ ``Tag``.
.. _operator||:
``operator||``
.. parsed-literal::
template <class F> *tagged lazy default* operator||(F const& g) const;
:Requires: ``g()`` is valid, with type ``boost::``\ |result_of|_\
``<F()>::type``. [#no_result_of]_
:Returns: a |tagged lazy default| with *value* ``g`` and |kw|_ ``Tag``.
.. _get:
``get``
.. parsed-literal::
static keyword<Tag>& get\();
:Returns: a “singleton instance”: the same object will be
returned on each invocation of ``get()``.
:Thread Safety: ``get()`` can be called from multiple threads
simultaneously.
``parameters``
--------------
Provides an interface for assembling the actual arguments to a
`forwarding function` into an |ArgumentPack|, in which any
|positional| arguments will be tagged according to the
corresponding template argument to ``parameters``.
.. _forwarding function: `forwarding functions`_
:Defined in: `boost/parameter/parameters.hpp`__
__ ../../../../boost/parameter/parameters.hpp
.. parsed-literal::
template <class P0 = *unspecified*, class P1 = *unspecified*, …class P\ β = *unspecified*>
struct parameters
{
template <class A0, class A1 = *unspecified*, …class A\ β = *unspecified*>
struct `match`_
{
typedef … type;
};
template <class A0>
|ArgumentPack|_ `operator()`_\(A0 const& a0) const;
template <class A0, class A1>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1) const;
:large:`⋮`
template <class A0, class A1, …class A\ β>
|ArgumentPack|_ `operator()`_\(A0 const& a0, A1 const& a1, …A\ β const& a\ β) const;
};
:Requires: ``P0``, ``P1``, … ``P``\ β are models of |ParameterSpec|_.
.. Note::
In this section, ``R``\ *i* and ``K``\ *i* are defined as
follows, for any argument type ``A``\ *i*:
| ``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|.
.. _match:
``match``
A |Metafunction|_ used to remove a `forwarding function`_ from overload resolution.
:Returns: if ``P0``, ``P1``, …\ ``P``\ β are *satisfied* (see
below), then ``parameters<P0,P1,…Pβ>``. Otherwise,
``match<A0,A1,…Aβ>::type`` is not defined.
``P0``, ``P1``, …\ ``P``\ β are **satisfied** if, for
every *j* in 0…β, either:
* ``P``\ *j* is the *unspecified* default
* **or**, ``P``\ *j* is a specialization of |keyword|_,
* **or**, ``P``\ *j* is |optional|_ ``<X,F>`` and either
- ``X`` is not ``K``\ *i* for any *i*,
- **or** ``X`` is some ``K``\ *i* and ``mpl::apply<F,R``\ *i*\
``>::type::value`` is ``true``
* **or**, ``P``\ *j* is |required|_ ``<X,F>``, and
- ``X`` is some ``K``\ *i*, **and**
- ``mpl::apply<F,R``\ *i*\ ``>::type::value`` is ``true``
.. _operator():
``operator()``
.. parsed-literal::
template <class A0> |ArgumentPack|_ operator()(A0 const& a0) const;
:large:`⋮`
template <class A0, …class A\ β> |ArgumentPack|_ `operator()`_\(A0 const& a0, …A\ β const& a\ β) const;
:Returns:
An |ArgumentPack|_ containing, for each ``a``\ *i*,
- if ``a``\ *i*, is a single-element |ArgumentPack|, its element
- Otherwise, a |tagged reference| with |kw|_ ``K``\ *i* and *value* ``a``\ *i*
.. |optional| replace:: ``optional``
.. |required| replace:: ``required``
.. _optional:
.. _required:
``optional``, ``required``
--------------------------
These templates describe the requirements on a function parameter.
:Defined in: `boost/parameter/parameters.hpp`__
__ ../../../../boost/parameter/parameters.hpp
:Specializations model: |ParameterSpec|_
.. parsed-literal::
template <class Tag, class Predicate = *unspecified*>
struct optional;
template <class Tag, class Predicate = *unspecified*>
struct required;
The default value of ``Predicate`` is an unspecified |Metafunction|_ that returns
``mpl::true_`` for any argument.
.. |Metafunction| replace:: :concept:`Metafunction`
.. _Metafunction: ../../../mpl/doc/refmanual/metafunction.html
//////////////////////////////////////////////////////////////////////////////
Metafunctions
=============
A |Metafunction|_ is conceptually a function that operates on, and
returns, C++ types.
``binding``
-----------
Returns the result type of indexing an argument pack with a
|keyword tag type| or with a |tagged default|.
:Defined n: `boost/parameter/binding.hpp`__
__ ../../../../boost/parameter/binding.hpp
.. parsed-literal::
template <class A, class K, class D = void>
struct binding
{
typedef … type;
};
:Requires: ``A`` is a model of |ArgumentPack|_.
:Returns: the reference type of the |tagged reference| in ``A``
having |keyword tag type| ``K``, if any. If no such |tagged
reference| exists, returns ``D``.
``lazy_binding``
----------------
Returns the result type of indexing an argument pack with a |tagged
lazy default|.
:Defined in:
`boost/parameter/binding.hpp`__
__ ../../../../boost/parameter/binding.hpp
.. parsed-literal::
template <class A, class K, class F>
struct lazy_binding
{
typedef … type;
};
:Requires: ``A`` is a model of |ArgumentPack|_.
:Returns: the reference type of the |tagged reference| in ``A``
having |keyword tag type| ``K``, if any. If no such |tagged
reference| exists, returns ``boost::``\ |result_of|_\ ``<F()>::type``. [#no_result_of]_
//////////////////////////////////////////////////////////////////////////////
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_FUN(r,n,l,h,p)``
----------------------------------
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
positional arguments.
:Defined in: `boost/parameter/macros.hpp`__
__ ../../../../boost/parameter/macros.hpp
:Requires: ``l`` and ``h`` are nonnegative integer tokens such
that ``l`` < ``h``
Generates
.. parsed-literal::
template <class A1, class A2, …class A##\ **l**>
r name(
A1 const& a1, A2 const& a2, …A\ **l** const& x\ **l**
, typename **p**::match<A1,A2,…A\ **l**>::type p = **p**\ ())
{
return **name**\ _with_named_params(**p**\ (x1,x2,…x\ **l**));
}
template <class A1, class A2, …class A\ **l**, class A\ ##\ BOOST_PP_INC_\ (**l**)>
r name(
A1 const& a1, A2 const& a2, …A\ **l** const& x\ **l**
, A\ ##\ BOOST_PP_INC_\ (**l**) const& x\ ##\ BOOST_PP_INC_\ (**l**)
, 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**)));
}
:large:`⋮`
template <class A1, class A2, …class A\ **h**>
r name(
A1 const& a1, A2 const& a2, …A\ **h** const& x\ **h**
, typename **p**::match<A1,A2,…A\ **h**>::type p = **p**\ ())
{
return **name**\ _with_named_params(**p**\ (a1,a2,…a\ **h**));
}
.. _BOOST_PP_INC: ../../../preprocessor/doc/ref/inc.html
``BOOST_PARAMETER_KEYWORD(n,k)``
--------------------------------
Generates the declaration of a |keyword tag type| named ``k`` in
namespace ``n``, and a corresponding |keyword object| definition in
the enclosing namespace.
:Defined in: `boost/parameter/keyword.hpp`__
__ ../../../../boost/parameter/keyword.hpp
Generates
.. parsed-literal::
namespace **n** { struct **k**; }
namespace {
boost::parameter::keyword<*tag-namespace*::**k**>& **k**
= boost::parameter::keyword<*tag-namespace*::**k**>::get();
}
``BOOST_PARAMETER_MATCH(p,a,x)``
--------------------------------
Generates a defaulted parameter declaration for a `forwarding
function`_.
:Defined in: `boost/parameter/match.hpp`__
__ ../../../../boost/parameter/match.hpp
:Requires: ``a`` is a `Boost.Preprocessor sequence`__
of the form
.. parsed-literal::
(A0)(A1)…(A\ *n*)
__ http://www.boost.org/libs/preprocessor/doc/data.html
Generates
.. parsed-literal::
typename **p**::match<**A0**\ ,\ **A1**\ …,\ **A**\ *n*>::type **x** = **p**\ ()
Configuration Macros
====================
``BOOST_PARAMETER_MAX_ARITY``
-----------------------------
Determines the maximum number of arguments supported by the
library. Will only be ``#defined`` by the library if it is not
already ``#defined``.
.. |BOOST_PARAMETER_MAX_ARITY| replace:: ``BOOST_PARAMETER_MAX_ARITY``
:Defined in: `boost/parameter/config.hpp`__
__ ../../../../boost/parameter/config.hpp
:Default Value: ``5``
Tutorial
========
Follow `this link`__ to the Boost.Parameter tutorial
documentation.
__ index.html#tutorial
//////////////////////////////////////////////////////////////
.. [#thread] References to tag objects may be initialized multiple
times. This scenario can only occur in the presence of
threading. Because the C++ standard doesn't consider threading,
it doesn't explicitly allow or forbid multiple initialization of
references. That said, it's hard to imagine an implementation
where it could make a difference.
.. [#no_result_of] Where |BOOST_NO_RESULT_OF|_ is ``#defined``,
``boost::``\ |result_of|_\ ``<F()>::type`` is replaced by
``F::result_type``.
.. |result_of| replace:: ``result_of``
.. _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

View File

@@ -1,16 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2005. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#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/macros.hpp>
#include <boost/parameter/match.hpp>
#endif // BOOST_PARAMETER_050401_HPP

View File

@@ -6,18 +6,28 @@
#ifndef ARG_LIST_050329_HPP
#define ARG_LIST_050329_HPP
#include <boost/mpl/apply.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/result_of0.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/maybe_fwd.hpp>
#include <boost/parameter/config.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/iterator_tags.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/optional.hpp>
namespace boost { namespace parameter {
// Forward declaration for aux::arg_list, below.
@@ -36,9 +46,13 @@ namespace aux {
// match against keywords.
//
// MPL sequence support
struct arg_list_tag;
// Terminates arg_list<> and represents an empty list. Since this
// is just the terminating case you might want to look at arg_list
// first, to get a feel for what's really happening here.
struct empty_arg_list
{
empty_arg_list() {}
@@ -63,6 +77,12 @@ struct empty_arg_list
};
};
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// Terminator for has_key, indicating that the keyword is unique
template <class KW>
static no_tag has_key(KW*);
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| (BOOST_WORKAROUND(__GNUC__, < 3)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
@@ -123,8 +143,17 @@ struct empty_arg_list
template <class ParameterRequirements>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
// MPL sequence support
typedef empty_arg_list type; // convenience
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<class KW>
no_tag operator*(empty_arg_list, KW*);
#endif
// Forward declaration for arg_list::operator,
template <class KW, class T>
struct tagged_argument;
@@ -134,6 +163,7 @@ struct tagged_argument;
template <class TaggedArg, class Next = empty_arg_list>
struct arg_list : Next
{
typedef arg_list<TaggedArg,Next> self;
typedef typename TaggedArg::key_type key_type;
typedef typename TaggedArg::value_type value_type;
typedef typename TaggedArg::reference reference;
@@ -179,6 +209,26 @@ struct arg_list : Next
};
};
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !BOOST_WORKAROUND(__GNUC__, == 2)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
friend yes_tag operator*(arg_list, key_type*);
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) (*(next*)0 * (key*)0)
# else
// Overload for key_type, so the assert below will fire if the
// same keyword is used again
static yes_tag has_key(key_type*);
using Next::has_key;
# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
# endif
BOOST_MPL_ASSERT_MSG(
sizeof(BOOST_PARAMETER_CALL_HAS_KEY(Next,key_type)) == sizeof(no_tag)
, duplicate_keyword, (key_type)
);
# undef BOOST_PARAMETER_CALL_HAS_KEY
#endif
//
// Begin implementation of indexing operators for looking up
// specific arguments by name
@@ -240,38 +290,56 @@ struct arg_list : Next
// reached, indicating no matching argument was passed, the
// default is returned, or if no default_ or lazy_default was
// passed, compilation fails.
reference get(keyword<key_type> const& x) const
reference get(keyword<key_type> const&) const
{
return arg.value;
}
template <class Default>
reference get(default_<key_type,Default> x) const
reference get(default_<key_type,Default>) const
{
return arg.value;
}
template <class Default>
reference get(lazy_default<key_type, Default> x) const
reference get(lazy_default<key_type, Default>) const
{
return arg.value;
}
#else
reference operator[](keyword<key_type> const& x) const
typedef typename mpl::eval_if<
is_maybe<value_type>
, get_reference<value_type>
, mpl::identity<reference>
>::type default_reference;
reference operator[](keyword<key_type> const&) const
{
return arg.value;
}
template <class Default>
reference operator[](default_<key_type, Default> x) const
template <class T, class D>
default_reference get_value(T&, D&) const
{
return arg.value;
}
template <class T, class D>
default_reference get_value(maybe<T>&, D& x) const
{
return arg.value ? arg.value.get() : x;
}
template <class Default>
reference operator[](lazy_default<key_type, Default> x) const
default_reference operator[](default_<key_type, Default> const& x) const
{
return get_value(arg.value, x.value);
}
template <class Default>
reference operator[](lazy_default<key_type, Default>) const
{
return arg.value;
}
@@ -303,23 +371,68 @@ struct arg_list : Next
using Next::satisfies;
#endif
#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class KW, class T2>
arg_list<tagged_argument<KW, T2>, arg_list>
operator,(tagged_argument<KW, T2> x) const
arg_list<tagged_argument<KW, T2>, self>
operator,(tagged_argument<KW,T2> x)
{
return arg_list<tagged_argument<KW, T2>, arg_list>(x, *this);
return arg_list<tagged_argument<KW,T2>, self>(x, *this);
}
#endif
// MPL sequence support
typedef self type; // Convenience for users
typedef Next tail_type; // For the benefit of iterators
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
template <> struct arg_list<int,int> {};
#endif
}}} // namespace boost::parameter::aux
// MPL sequence support
template <class ArgumentPack>
struct arg_list_iterator
{
typedef mpl::forward_iterator_tag category;
// The incremented iterator
typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
// dereferencing yields the key type
typedef typename ArgumentPack::key_type type;
};
template <>
struct arg_list_iterator<empty_arg_list> {};
}} // namespace parameter::aux
// MPL sequence support
namespace mpl
{
template <>
struct begin_impl<parameter::aux::arg_list_tag>
{
template <class S>
struct apply
{
typedef parameter::aux::arg_list_iterator<S> type;
};
};
template <>
struct end_impl<parameter::aux::arg_list_tag>
{
template <class>
struct apply
{
typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
};
};
}
} // namespace boost
#endif // ARG_LIST_050329_HPP

View File

@@ -0,0 +1,52 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_MAYBE_051212_HPP
# define BOOST_PARAMETER_MAYBE_051212_HPP
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/optional.hpp>
# include <boost/mpl/if.hpp>
namespace boost { namespace parameter { namespace aux {
struct empty_maybe_tag {};
template <class T>
struct maybe
{
typedef typename mpl::if_<
is_reference<T>
, T
, typename add_reference<typename add_const<T>::type>::type
>::type reference;
maybe()
{}
explicit maybe(reference x)
: value(x)
{}
typedef reference(maybe<T>::*safe_bool)() const;
operator safe_bool() const
{
return value ? &maybe<T>::get : 0 ;
}
reference get() const
{
return value.get();
}
boost::optional<T> value;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_MAYBE_051212_HPP

View File

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_MAYBE_FWD_051212_HPP
# define BOOST_PARAMETER_MAYBE_FWD_051212_HPP
# include <boost/detail/is_xxx.hpp>
namespace boost { namespace parameter { namespace aux {
template <class T>
struct maybe;
BOOST_DETAIL_IS_XXX_DEF(maybe,maybe,1)
template <class T>
struct get_reference
{
typedef typename T::reference type;
};
}}} // namespace boost::parameter::aux
#endif // BOOST_PARAMETER_MAYBE_FWD_051212_HPP

View File

@@ -5,12 +5,10 @@
# define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
# include <boost/parameter/aux_/unwrap_cv_reference.hpp>
# include <boost/parameter/aux_/tagged_argument.hpp>
namespace boost { namespace parameter { namespace aux {
template <class Keyword, class Arg>
struct tagged_argument;
template <class Keyword, class ActualArg
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, class = typename is_cv_reference_wrapper<ActualArg>::type

View File

@@ -8,6 +8,7 @@
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/arg_list.hpp>
#include <boost/detail/is_xxx.hpp>
namespace boost { namespace parameter { namespace aux {
@@ -42,11 +43,16 @@ struct tagged_argument
}
reference value;
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
// warning suppression
private:
void operator=(tagged_argument const&);
#endif
};
// Defines a metafunction, is_tagged_argument, that identifies
// tagged_argument specializations.
BOOST_PYTHON_IS_XXX_DEF(tagged_argument,tagged_argument,2)
BOOST_DETAIL_IS_XXX_DEF(tagged_argument,tagged_argument,2)
}}} // namespace boost::parameter::aux

View File

@@ -105,13 +105,28 @@ struct keyword : noncopyable
// Reduces boilerplate required to declare and initialize keywords
// without violating ODR. Declares a keyword tag type with the given
// name in namespace tag_namespace, and declares and initializes a
//
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get();
// name in namespace tag_namespace, and declares and initializes a
// reference in an anonymous namespace to a singleton instance of that
// type.
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
static ::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get();
#else
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
namespace \
{ \
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get(); \
}
#endif
}} // namespace boost::parameter

View File

@@ -78,7 +78,7 @@
#define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(Params const&); \
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p); \
\
BOOST_PP_REPEAT_FROM_TO( \
lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \

View File

@@ -6,6 +6,8 @@
#ifndef BOOST_PARAMETERS_031014_HPP
#define BOOST_PARAMETERS_031014_HPP
#include <boost/detail/is_xxx.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/always.hpp>
@@ -19,8 +21,6 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/iterator/detail/config_def.hpp>
#include <boost/python/detail/is_xxx.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
@@ -66,6 +66,9 @@ namespace aux { struct use_default {}; }
// required<...>, wrapper, it is treated as though optional<k> were
// specified.
//
// If a keyword k is specified with unnamed<...>, that keyword
// will be automatically deduced from the argument list.
//
template <class Tag, class Predicate = aux::use_default>
struct required
{
@@ -90,10 +93,10 @@ struct unnamed
namespace aux
{
// Defines metafunctions, is_required and is_optional, that
// identify required<...> and optional<...> specializations.
BOOST_PYTHON_IS_XXX_DEF(required, required, 2)
BOOST_PYTHON_IS_XXX_DEF(optional, optional, 2)
BOOST_PYTHON_IS_XXX_DEF(unnamed, unnamed, 2)
// identify required<...>, optional<...> and unnamed<...> specializations.
BOOST_DETAIL_IS_XXX_DEF(required, required, 2)
BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2)
BOOST_DETAIL_IS_XXX_DEF(unnamed, unnamed, 2)
//
// key_type, has_default, and predicate --
@@ -104,7 +107,7 @@ namespace aux
// argument type is required match.
//
// a ParameterSpec is a specialization of either keyword<...>,
// required<...> or optional<...>.
// required<...>, optional<...> or unnamed<...>
//
// helper for key_type<...>, below.
@@ -159,6 +162,7 @@ namespace aux
mpl::or_<
is_optional<T>
, is_required<T>
, is_unnamed<T>
>
, get_predicate<T>
, mpl::identity<mpl::always<mpl::true_> >
@@ -335,6 +339,16 @@ namespace aux
};
};
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
template<class T>
struct is_string_literal : mpl::false_
{};
template<int N>
struct is_string_literal<char const[N]> : mpl::true_
{};
#endif
// Used by as_tagged_argument to match a given
// argument with a list of unnamed specs.
//
@@ -369,13 +383,27 @@ namespace aux
template <class Arg, class DefaultTag>
struct apply
{
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
typedef typename mpl::if_<
is_string_literal<Arg>
, char const*
, Arg
>::type const arg_type;
#else
typedef Arg const arg_type;
#endif
typedef typename mpl::eval_if<
typename mpl::apply1<typename ParameterSpec::predicate, Arg>::type
, mpl::pair<
typename tag<typename ParameterSpec::key_type, Arg const>::type
typename tag<typename ParameterSpec::key_type, arg_type>::type
, Tail
>
, eval_tail<Arg, DefaultTag>
,
#if BOOST_WORKAROUND(__GNUC__, < 3)
typename unnamed_list<ParameterSpec, Tail>::template
#endif
eval_tail<Arg, DefaultTag>
>::type type;
};
};
@@ -578,7 +606,5 @@ struct parameters
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_PARAMETERS_031014_HPP

View File

@@ -0,0 +1,103 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_INVOKER_051210_HPP
# define BOOST_PARAMETER_INVOKER_051210_HPP
# include <boost/mpl/begin.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/parameter/keyword.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
namespace boost { namespace parameter { namespace python { namespace aux {
template <long Arity, class M, class R, class Args>
struct invoker;
template <class M, class R>
struct make_invoker
{
template <class Args>
struct apply
{
typedef invoker<
mpl::size<Args>::value, M, R, Args
> type;
};
};
template <long Arity, class T, class R, class Args>
struct call_invoker;
template <class T, class R>
struct make_call_invoker
{
template <class Args>
struct apply
{
typedef call_invoker<
mpl::size<Args>::value, T, R, Args
> type;
};
};
template <long Arity, class T, class Args>
struct init_invoker;
template <class T>
struct make_init_invoker
{
template <class Args>
struct apply
{
typedef init_invoker<
mpl::size<Args>::value, T, Args
> type;
};
};
template <class M, class R, class Args>
struct invoker<0, M, R, Args>
{
static R execute()
{
return M()(boost::type<R>());
}
};
template <class T, class R, class Args>
struct call_invoker<0, T, R, Args>
{
static R execute(T& self)
{
return self();
}
};
template <class T, class Args>
struct init_invoker<0, T, Args>
{
static T* execute(T& self)
{
return new T;
}
};
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 1))
# include BOOST_PP_ITERATE()
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 2))
# include BOOST_PP_ITERATE()
# define BOOST_PP_ITERATION_PARAMS_1 (4, \
(1, BOOST_PARAMETER_MAX_ARITY, <boost/parameter/python/aux_/invoker_iterate.hpp>, 3))
# include BOOST_PP_ITERATE()
}}}} // namespace boost::parameter::python::aux
#endif // BOOST_PARAMETER_INVOKER_051210_HPP

View File

@@ -0,0 +1,87 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/dec.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define N BOOST_PP_ITERATION()
#define BOOST_PARAMETER_PY_ARG_TYPES(z, n, _) \
typedef typename mpl::next< \
BOOST_PP_CAT(iter,BOOST_PP_DEC(n)) \
>::type BOOST_PP_CAT(iter,n); \
\
typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type BOOST_PP_CAT(spec,n); \
typedef typename mpl::if_< \
mpl::and_< \
mpl::not_<typename BOOST_PP_CAT(spec,n)::required> \
, typename BOOST_PP_CAT(spec,n)::optimized_default \
> \
, parameter::aux::maybe<typename BOOST_PP_CAT(spec,n)::type> \
, typename BOOST_PP_CAT(spec,n)::type \
>::type BOOST_PP_CAT(arg,n); \
typedef typename BOOST_PP_CAT(spec,n)::keyword BOOST_PP_CAT(kw,n);
#if BOOST_PP_ITERATION_FLAGS() == 1
template <class M, class R, class Args>
struct invoker<N, M, R, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 2
template <class T, class R, class Args>
struct call_invoker<N, T, R, Args>
#elif BOOST_PP_ITERATION_FLAGS() == 3
template <class T, class Args>
struct init_invoker<N, T, Args>
#endif
{
typedef typename mpl::begin<Args>::type iter0;
typedef typename mpl::deref<iter0>::type spec0;
typedef typename mpl::if_<
mpl::and_<
mpl::not_<typename spec0::required>
, typename spec0::optimized_default
>
, parameter::aux::maybe<typename spec0::type>
, typename spec0::type
>::type arg0;
typedef typename spec0::keyword kw0;
BOOST_PP_REPEAT_FROM_TO(1, N, BOOST_PARAMETER_PY_ARG_TYPES, ~)
static
#if BOOST_PP_ITERATION_FLAGS() == 1 || BOOST_PP_ITERATION_FLAGS() == 2
R
#else
T*
#endif
execute(
#if BOOST_PP_ITERATION_FLAGS() == 2
T& self
,
#endif
BOOST_PP_ENUM_BINARY_PARAMS(N, arg, a)
)
{
return
#if BOOST_PP_ITERATION_FLAGS() == 1
M()(
boost::type<R>()
, BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 2
self(
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#elif BOOST_PP_ITERATION_FLAGS() == 3
new T(
BOOST_PP_ENUM_BINARY_PARAMS(N, keyword<kw, >::get() = a)
);
#endif
}
};
#undef BOOST_PARAMETER_PY_ARG_TYPES
#undef N

View File

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

View File

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

View File

@@ -0,0 +1,94 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_MAKE_FUNCTION_051130_HPP
# define BOOST_PARAMETER_MAKE_FUNCTION_051130_HPP
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/python/args.hpp>
#include <boost/python/make_function.hpp>
#include <boost/python/default_call_policies.hpp>
namespace boost { namespace parameter { namespace python {
namespace detail
{
// Used as start value in the recursive arg() composition below.
struct no_keywords
{
template <class T>
T const& operator,(T const& x) const
{
return x;
}
};
template <class T, class Iter, class End, class Keywords, class K>
boost::python::object make_function_aux0(
T* p, Iter, End e, Keywords const& keywords, mpl::pair<mpl::true_,K>)
{
return make_function_aux(
p, typename mpl::next<Iter>::type(), e
, (
keywords, boost::python::arg(K::keyword())
)
);
}
template <class T, class Iter, class End, class Keywords, class K>
boost::python::object make_function_aux0(
T* p, Iter, End e, Keywords const& keywords, mpl::pair<mpl::false_,K>)
{
return make_function_aux(
p, typename mpl::next<Iter>::type(), e
, (
keywords, boost::python::arg(K::keyword()) = T::default_(K())
)
);
}
template <class T, class Iter, class End, class Keywords>
boost::python::object make_function_aux(
T* p, Iter i, End e, Keywords const& keywords)
{
return make_function_aux0(
p, i, e, keywords, typename mpl::deref<Iter>::type()
);
}
template <class T, class End, class Keywords>
boost::python::object make_function_aux(
T*, End, End, Keywords const& keywords)
{
return boost::python::make_function(
T()
, boost::python::default_call_policies()
, keywords
, typename T::signature()
);
}
} // namespace detail
template <class T>
boost::python::object make_function()
{
typedef typename T::keywords keywords;
return detail::make_function_aux(
(T*)0
, typename mpl::begin<keywords>::type()
, typename mpl::end<keywords>::type()
, detail::no_keywords()
);
}
}}} // namespace boost::parameter::python
#endif // BOOST_PARAMETER_MAKE_FUNCTION_051130_HPP

9
index.html Executable file
View File

@@ -0,0 +1,9 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatically loading index page... if nothing happens, please go to
<a href="doc/index.html">doc/html/index.html</a>.
</body>
</html>

19
test/Jamfile Executable file
View File

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

18
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,18 @@
# Boost Parameter Library test Jamfile
project boost/parameter
: default-build <warnings>off
;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ run unnamed.cpp ]
[ run tutorial.cpp ]
[ run earwicker.cpp ]
[ run mpl.cpp ]
[ run efficiency.cpp : : : <variant>release ]
[ compile unwrap_cv_reference.cpp ]
[ compile-fail duplicates.cpp ]
;

112
test/basics.cpp Executable file
View File

@@ -0,0 +1,112 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <cassert>
#include <string.h>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include "basics.hpp"
namespace test
{
// A separate function for getting the "value" key, so we can deduce
// F and use lazy_binding on it.
template <class Params, class F>
typename boost::parameter::lazy_binding<Params,tag::value,F>::type
extract_value(Params const& p, F const& f)
{
typename boost::parameter::lazy_binding<
Params, tag::value, F
>::type v = p[value || f ];
return v;
}
template<class Params>
int f_impl(Params const& p)
{
typename boost::parameter::binding<Params, tag::name>::type
n = p[name];
typename boost::parameter::binding<
Params, tag::value, double
>::type v = extract_value(p, boost::bind(&value_default));
typename boost::parameter::binding<
Params, tag::index, int
>::type i =
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
p[test::index | 999];
#else
p[index | 999];
#endif
p[tester](n,v,i);
return 1;
}
template<class Tester, class Name, class Value, class Index>
int f(Tester const& t, const Name& name_,
const Value& value_, const Index& index_)
{
return f_impl(f_parameters()(t, name_, value_, index_));
}
template<class Tester, class Name, class Value>
int f(Tester const& t, const Name& name_, const Value& value_)
{
return f_impl(f_parameters()(t, name_, value_));
}
template<class Tester, class Name>
int f(Tester const& t, const Name& name_)
{
return f_impl(f_parameters()(t, name_));
}
template<class Params>
int f_list(Params const& params)
{
return f_impl(params);
}
}
int main()
{
using test::f;
using test::f_list;
using test::name;
using test::value;
using test::index;
using test::tester;
f(
test::values(S("foo"), S("bar"), S("baz"))
, S("foo"), S("bar"), S("baz")
);
int x = 56;
f(
test::values("foo", 666.222, 56)
, index = boost::ref(x), name = "foo"
);
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// No comma operator available on Borland
f_list((
tester = test::values("foo", 666.222, 56)
, index = boost::ref(x)
, name = "foo"
));
#endif
//f(index = 56, name = 55); // won't compile
return 0;
}

111
test/basics.hpp Executable file
View File

@@ -0,0 +1,111 @@
// Copyright David Abrahams, Daniel Wallin 2005. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BASICS_050424_HPP
#define BASICS_050424_HPP
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, name)
BOOST_PARAMETER_KEYWORD(tag, value)
BOOST_PARAMETER_KEYWORD(tag, index)
BOOST_PARAMETER_KEYWORD(tag, tester)
using namespace boost::parameter;
struct f_parameters // vc6 is happier with inheritance than with a typedef
: parameters<
tag::tester
, tag::name
, tag::value
, tag::index
>
{};
inline double value_default()
{
return 666.222;
}
template <class T>
inline bool equal(T const& x, T const& y)
{
return x == y;
}
inline bool equal(char const* s1, char const* s2)
{
return !strcmp(s1,s2);
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
inline bool equal(char* s1, char* s2)
{
return !strcmp(s1,s2);
}
#endif
template <class Name, class Value, class Index>
struct values_t
{
values_t(Name const& n, Value const& v, Index const& i)
: n(n), v(v), i(i)
{}
template <class Name_, class Value_, class Index_>
void operator()(Name_ const& n_, Value_ const& v_, Index_ const& i_) const
{
// Only VC and its emulators fail this; they seem to have
// problems with deducing the constness of string literal
// arrays.
#if defined(_MSC_VER) \
&& (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, < 1310)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# else
BOOST_MPL_ASSERT((boost::is_same<Index,Index_>));
BOOST_MPL_ASSERT((boost::is_same<Value,Value_>));
BOOST_MPL_ASSERT((boost::is_same<Name,Name_>));
#endif
BOOST_ASSERT(equal(n, n_));
BOOST_ASSERT(equal(v, v_));
BOOST_ASSERT(equal(i, i_));
}
Name const& n;
Value const& v;
Index const& i;
};
template <class Name, class Value, class Index>
inline values_t<Name,Value,Index>
values(Name const& n, Value const& v, Index const& i)
{
return values_t<Name,Value,Index>(n,v,i);
}
} // namespace test
// GCC2 has a problem with char (&)[] deduction, so we'll cast string
// literals there.
#undef S
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define S(s) (char const*)s
#else
# define S(s) s
#endif
#endif // BASICS_050424_HPP

24
test/duplicates.cpp Executable file
View File

@@ -0,0 +1,24 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <string.h>
#include "basics.hpp"
namespace test
{
template <class Params>
void f(Params const &) {}
}
int main()
{
using namespace test;
f((name = 1, value = 1, index = 1, tester = 1,
value = 1 // repeated keyword: should not compile
));
return 0;
}

56
test/earwicker.cpp Executable file
View File

@@ -0,0 +1,56 @@
// Copyright David Abrahams, Daniel Wallin 2005. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/placeholders.hpp>
#include <iostream>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
BOOST_PARAMETER_KEYWORD(tag, z)
using namespace boost::parameter;
using namespace boost::mpl::placeholders;
struct f_parameters // vc6 is happier with inheritance than with a typedef
: parameters<
optional<tag::x,boost::is_convertible<_,int> >
, optional<tag::y,boost::is_convertible<_,int> >
, optional<tag::z,boost::is_convertible<_,int> >
>
{};
#ifdef BOOST_NO_VOID_RETURNS
BOOST_PARAMETER_FUN(int, f, 0, 3, f_parameters)
#else
BOOST_PARAMETER_FUN(void, f, 0, 3, f_parameters)
#endif
{
std::cout << "x = " << p[x | -1] << std::endl;
std::cout << "y = " << p[y | -2] << std::endl;
std::cout << "z = " << p[z | -3] << std::endl;
std::cout << "================" << std::endl;
#ifdef BOOST_NO_VOID_RETURNS
return 0;
#endif
}
}
int main()
{
using namespace test;
f(x = 1, y = 2, z = 3);
f(x = 1);
f(y = 2);
f(z = 3);
f(z = 3, x = 1);
}

171
test/efficiency.cpp Executable file
View File

@@ -0,0 +1,171 @@
// Copyright David Abrahams, Matthias Troyer, Michael Gauckler
// 2005. Distributed under the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <boost/timer.hpp>
#include <iostream>
namespace test
{
//
// This test measures the abstraction overhead of using the named
// parameter interface. Some actual test results have been recorded
// in timings.txt in this source file's directory, or
// http://www.boost.org/libs/parameter/test/timings.txt.
//
// Caveats:
//
// 1. This test penalizes the named parameter library slightly, by
// passing two arguments through the named interface, while
// only passing one through the plain C++ interface.
//
// 2. This test does not measure the case where an ArgumentPack is
// so large that it doesn't fit in the L1 cache.
//
// 3. Although we've tried to make this test as general as
// possible, we are targeting it at a specific application.
// Where that affects design decisions, we've noted it below in
// ***...***.
//
// 4. The first time you run this program, the time may not be
// representative because of disk and memory cache effects, so
// always run it multiple times and ignore the first
// measurement. This approach will also allow you to estimate
// the statistical error of your test by observing the
// variation in the valid times.
//
// 5. Try to run this program on a machine that's otherwise idle,
// or other processes and even device hardware interrupts may
// interfere by causing caches to be flushed.
// Accumulator function object with plain C++ interface
template <class T>
struct plain_weight_running_total
{
plain_weight_running_total()
: sum(0)
{}
void operator()(T w)
{
this->sum += w;
}
T sum;
};
BOOST_PARAMETER_KEYWORD(tag, weight)
BOOST_PARAMETER_KEYWORD(tag, value)
// Accumulator function object with named parameter interface
template <class T>
struct named_param_weight_running_total
{
named_param_weight_running_total()
: sum(0)
{}
template <class ArgumentPack>
void operator()(ArgumentPack const& variates)
{
this->sum += variates[weight];
}
T sum;
};
// This value is required to ensure that a smart compiler's dead
// code elimination doesn't optimize away anything we're testing.
// We'll use it to compute the return code of the executable to make
// sure it's needed.
double live_code;
// Call objects of the given Accumulator type repeatedly with x as
// an argument.
template <class Accumulator, class Arg>
void hammer(Arg const& x)
{
// Strategy: because the sum in an accumulator after each call
// depends on the previous value of the sum, the CPU's pipeline
// might be stalled while waiting for the previous addition to
// complete. Therefore, we allocate an array of accumulators,
// and update them in sequence, so that there's no dependency
// between adjacent addition operations.
//
// Additionally, if there were only one accumulator, the
// compiler or CPU might decide to update the value in a
// register rather that writing it back to memory. we want each
// operation to at least update the L1 cache. *** Note: This
// concern is specific to the particular application at which
// we're targeting the test. ***
// This has to be at least as large as the number of
// simultaneous accumulations that can be executing in the
// compiler pipeline. A safe number here is larger than the
// machine's maximum pipeline depth. If you want to test the L2
// or L3 cache, or main memory, you can increase the size of
// this array. 1024 is an upper limit on the pipeline depth of
// current vector machines.
const std::size_t number_of_accumulators = 1024;
Accumulator a[number_of_accumulators];
for (long iteration = 0; iteration < 1000000; ++iteration)
{
for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
{
(*ap)(x);
}
}
// Accumulate all the partial sums to avoid dead code
// elimination.
for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
{
live_code += ap->sum;
}
}
// Measure the time required to hammer accumulators of the given
// type with the argument x.
template <class Accumulator, class T>
double measure(T const& x)
{
// Hammer accumulators a couple of times to ensure the
// instruction cache is full of our test code, and that we don't
// measure the cost of a page fault for accessing the data page
// containing the memory where the accumulators will be
// allocated
hammer<Accumulator>(x);
hammer<Accumulator>(x);
// Now start a timer
boost::timer time;
hammer<Accumulator>(x); // This time, we'll measure
return time.elapsed();
}
}
int main()
{
using namespace test;
std::cout
<< "plain time: "
<< measure<plain_weight_running_total<double> >(.1)
<< std::endl;
std::cout
<< "named parameter time: "
<< measure<named_param_weight_running_total<double> >(
(weight = .1, value = .2)
)
<< std::endl;
// This is ultimately responsible for preventing all the test code
// from being optimized away. Change this to return 0 and you
// unplug the whole test's life support system.
return live_code < 0.;
}

57
test/macros.cpp Executable file
View File

@@ -0,0 +1,57 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/bind.hpp>
#include <boost/static_assert.hpp>
#include <boost/ref.hpp>
#include <cassert>
#include <string.h>
#include "basics.hpp"
namespace test
{
BOOST_PARAMETER_FUN(int, f, 2, 4, f_parameters)
{
p[tester](
p[name]
, p[value || boost::bind(&value_default) ]
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
, p[test::index | 999 ]
#else
, p[index | 999 ]
#endif
);
return 1;
}
} // namespace test
int main()
{
using test::f;
using test::name;
using test::value;
using test::index;
using test::tester;
f(
test::values(S("foo"), S("bar"), S("baz"))
, S("foo"), S("bar"), S("baz")
);
int x = 56;
f(
test::values("foo", 666.222, 56)
, index = boost::ref(x), name = "foo"
);
return 0;
}

88
test/mpl.cpp Executable file
View File

@@ -0,0 +1,88 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "basics.hpp"
#include <boost/mpl/list.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/size.hpp>
#include <boost/type_traits/add_pointer.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/find.hpp>
# include <boost/mpl/end.hpp>
namespace test
{
namespace mpl = boost::mpl;
template <class Set>
struct assert_in_set
{
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
}
};
template<class Expected, class Params>
void f_impl(Params const& p BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
{
BOOST_MPL_ASSERT_RELATION(
mpl::size<Expected>::value
, ==
, mpl::size<Params>::value
);
mpl::for_each<Params, boost::add_pointer<mpl::_1> >(assert_in_set<Expected>());
}
template<class Expected, class Tester, class Name, class Value, class Index>
void f(Tester const& t, const Name& name_,
const Value& value_, const Index& index_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
{
f_impl<Expected>(f_parameters()(t, name_, value_, index_));
}
template<class Expected, class Tester, class Name, class Value>
void f(Tester const& t, const Name& name_, const Value& value_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
{
f_impl<Expected>(f_parameters()(t, name_, value_));
}
template<class Expected, class Tester, class Name>
void f(Tester const& t, const Name& name_ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected))
{
f_impl<Expected>(f_parameters()(t, name_));
}
void run()
{
typedef test::tag::tester tester_;
typedef test::tag::name name_;
typedef test::tag::value value_;
typedef test::tag::index index_;
f<mpl::list4<tester_,name_,value_,index_> >(1, 2, 3, 4);
f<mpl::list3<tester_,name_,index_> >(1, 2, index = 3);
f<mpl::list3<tester_,name_,index_> >(1, index = 2, name = 3);
f<mpl::list2<name_,value_> >(name = 3, value = 4);
}
}
int main()
{
test::run();
return 0;
}

38
test/python/Jamfile Executable file
View File

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

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

@@ -0,0 +1,97 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <boost/python.hpp>
#include <boost/parameter/python/general.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/weighted_mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/order.hpp>
#include <boost/accumulators/statistics/order_variate.hpp>
#include <boost/accumulators/statistics/with_error.hpp>
#include <boost/accumulators/framework/parameters/weights.hpp>
#include <boost/accumulators/statistics/variates/covariate.hpp>
using namespace boost;
using namespace boost::accumulators;
typedef accumulator_set<
double
, stats<tag::order_variate<int, tag::covariate1> >
> accumulator_type;
template<typename Range>
python::list listify_range(Range const &range)
{
python::list l;
typedef typename boost::range_result_iterator<Range>::type iterator;
iterator begin = range.begin();
iterator end = range.end();
for(; begin != end; ++begin)
l.append(*begin);
return l;
}
python::list listify_covariate1(accumulator_type const& acc)
{
return listify_range(order_variate<int, tag::covariate1>(acc));
}
namespace boost { namespace accumulators { namespace tag
{
char const* keyword_name(sample*)
{
return "sample";
}
char const* keyword_name(covariate1*)
{
return "covariate1";
}
}}} // namespace boost::accumulators::tag
namespace boost { namespace accumulators { namespace detail
{
char const* keyword_name(cache_size_tag*)
{
return "cache_size";
}
}}} // namespace boost::accumulators::detail
BOOST_PYTHON_MODULE(accumulator_set)
{
using namespace boost::python;
namespace py = boost::parameter::python;
class_<accumulator_type>("accumulator_set", no_init)
.def(
py::init<
mpl::vector1<
accumulators::detail::cache_size_tag
>
, mpl::vector1<unsigned>
>()
)
.def(
py::call<
mpl::vector2<
tag::sample
, tag::covariate1
>
, mpl::vector3<void, double, int>
>()
);
def("covariate1", listify_covariate1);
}

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

@@ -0,0 +1,100 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <boost/parameter/python/general.hpp>
#include <boost/parameter/parameters.hpp>
namespace mpl = boost::mpl;
BOOST_PARAMETER_KEYWORD(tag, x)
BOOST_PARAMETER_KEYWORD(tag, y)
BOOST_PARAMETER_KEYWORD(tag, z)
struct tag::x
{
static char const* keyword()
{
return "x";
}
};
struct tag::y
{
static char const* keyword()
{
return "y";
}
};
struct tag::z
{
static char const* keyword()
{
return "z";
}
};
typedef boost::parameter::parameters<
tag::x
, tag::y
> f_parameters;
template <class Args>
float f_impl(Args const& args)
{
return args[x | 1] / args[y | 1];
}
template <class A0>
float f(A0 const& a0)
{
return f_impl(f_parameters()(a0));
}
template <class A0, class A1>
float f(A0 const& a0, A1 const& a1)
{
return f_impl(f_parameters()(a0,a1));
}
template <class A0, class A1, class A2>
float f(A0 const& a0, A1 const& a1, A2 const& a2)
{
return f_impl(f_parameters()(a0,a1,a2));
}
struct meta
{
typedef mpl::vector3<
mpl::pair<tag::x, mpl::true_>
, mpl::pair<tag::y, mpl::false_>
, mpl::pair<tag::z, mpl::false_>
> keywords;
template <class R, class A0>
R operator()(boost::type<R>, A0 const& a0)
{
return f(a0);
}
template <class R, class A0, class A1>
R operator()(boost::type<R>, A0 const& a0, A1 const& a1)
{
return f(a0,a1);
}
template <class R, class A0, class A1, class A2>
R operator()(boost::type<R>, A0 const& a0, A1 const& a1, A2 const& a2)
{
return f(a0,a1,a2);
}
};
BOOST_PYTHON_MODULE(general)
{
boost::parameter::python::def<meta>("f", mpl::vector4<float,float,float,float>());
}

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

@@ -0,0 +1,26 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <iostream>
#include "simple.hpp"
int add(int x, int y, int z, int u)
{
return x + y + z + u;
}
void print(int value, char const* name, float scale)
{
std::cout << "value = " << value << "\n";
std::cout << "name = " << name << "\n";
std::cout << "scale = " << scale << "\n";
}
BOOST_PYTHON_MODULE(parameter)
{
def("add", boost::parameter::python::make_function<add_meta>());
def("echo", boost::parameter::python::make_function<print_meta>());
}

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

@@ -0,0 +1,42 @@
// Copyright Daniel Wallin 2005. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_SIMPLE_051130_HPP
# define BOOST_PARAMETER_SIMPLE_051130_HPP
# include <boost/parameter/python/function.hpp>
# include <boost/parameter/python/make_function.hpp>
ZKB_KEYWORD(tag, x)
ZKB_KEYWORD(tag, y)
ZKB_KEYWORD(tag, z)
ZKB_KEYWORD(tag, u)
ZKB_FUNCTION(int, add, add_meta, tag,
(required
(x, int)
(y, int)
)
(optional
(z, int, 0)
(u, int, 0)
)
);
ZKB_KEYWORD(tag, value)
ZKB_KEYWORD(tag, name)
ZKB_KEYWORD(tag, scale)
ZKB_FUNCTION(void, print, print_meta, tag,
(required
(value, int)
)
(optional
(name, char const*, "unnamed")
(scale, float, 1.f)
)
);
#endif // BOOST_PARAMETER_SIMPLE_051130_HPP

View File

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

View File

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

View File

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

107
test/sfinae.cpp Executable file
View File

@@ -0,0 +1,107 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <boost/assert.hpp>
#include <string>
#include <boost/type_traits/is_convertible.hpp>
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
namespace test
{
BOOST_PARAMETER_KEYWORD(keywords,name)
BOOST_PARAMETER_KEYWORD(keywords,value)
using namespace boost::parameter;
struct f_parameters
: parameters<
optional<
keywords::name
, boost::is_convertible<boost::mpl::_, std::string>
>
, optional<
keywords::value
, boost::is_convertible<boost::mpl::_, float>
>
>
{};
// The use of assert_equal_string is just a nasty workaround for a
// vc++ 6 ICE.
void assert_equal_string(std::string x, std::string y)
{
BOOST_ASSERT(x == y);
}
template<class P>
void f_impl(P const& p)
{
float v = p[value | 3.f];
BOOST_ASSERT(v == 3.f);
assert_equal_string(p[name | "bar"], "foo");
}
void f()
{
f_impl(f_parameters()());
}
using boost::parameter::aux::void_;
template<class A0>
void f(
A0 const& a0
, BOOST_PARAMETER_MATCH(f_parameters, (A0), args))
{
f_impl(args(a0));
}
template<class A0, class A1>
void f(
A0 const& a0, A1 const& a1
, BOOST_PARAMETER_MATCH(f_parameters,(A0)(A1), args))
{
f_impl(args(a0, a1));
}
#ifndef BOOST_NO_SFINAE
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
// working. On all other compilers we're just checking that
// everything about SFINAE-enabled code will work, except of course
// the SFINAE.
template<class A0, class A1>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
f(A0 const& a0, A1 const& a1)
{
return 0;
}
#endif
} // namespace test
int main()
{
using test::name;
using test::value;
using test::f;
f("foo");
f("foo", 3.f);
f(value = 3.f, name = "foo");
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
}

128
test/timings.txt Executable file
View File

@@ -0,0 +1,128 @@
# Copyright David Abrahams 2005. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
----------------- Test #1 ----------------
Testers:
Matthias Troyer, Michael Gauckler, David Abrahams
Date:
2005-09-09
Compiler:
Cygwin g++-4.0.0
Command lines:
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops \
-O3 -finline-functions -Wno-inline -DNDEBUG efficiency.cpp
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
efficiency && efficiency && efficiency
Machine:
Dell Inspiron 9300
Intel(R) Pentium(R) M processor 2.00GHz
Running on 230 volts AC power
Timings:
Run #1 results discarded per standard practice
Run #2
plain time: 0.75
named parameter time: 0.734
Run #3
plain time: 0.781
named parameter time: 0.766
----------------- Test #2 ----------------
Testers:
Chris Frey
Date:
2005-09-17
Compiler:
Linux kernel 2.4.27
gcc version 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8)
Command lines:
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops \
-O3 -finline-functions -Wno-inline -DNDEBUG efficiency.cpp
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
Machine:
IBM Thinkpad 770Z, running on AC power
Intel Pentium II 366Mhz
Timings:
Run #1 results discarded per standard practice
Run #2
plain time: 6.42
named parameter time: 7.34
Run #3
plain time: 6.42
named parameter time: 7.34
----------------- Test #2 ----------------
Testers:
Stuar Dootson
Date:
2005-09-18
Machine:
Athlon 64 3500+ laptop, running on AC power
Windows XP SP2
Compiler: Visual C++ 7.1
command line:
cl -O2 efficiency.cpp -EHsc -I\lib\boost\include\boost-1_33
Results:
plain time: <ignored>
named parameter time: <ignored>
plain time: 1.453
named parameter time: 1.437
plain time: 1.453
named parameter time: 1.453
Compiler: Visual C++ 8.0
command-line:
cl -O2 efficiency.cpp -EHsc -I\lib\boost\include\boost-1_33
Results:
plain time: <ignored>
named parameter time: <ignored>
plain time: 1.438
named parameter time: 1.453
plain time: 1.438
named parameter time: 1.437
Compiler: Mingw gcc 3.4.2
command-line:
g++ -c -o efficiency.o -ftemplate-depth-100 -funroll-loops -O3
-finline-functions -Wno-inline -DNDEBUG efficiency.cpp
-I\lib\boost\include\boost-1_33
g++ -o efficiency.exe efficiency.o -Wl,--strip-all
Results:
plain time: <ignored>
named parameter time: <ignored>
plain time: 1.14
named parameter time: 1.422
plain time: 1.125
named parameter time: 1.406
-----------------------------------------

39
test/tutorial.cpp Executable file
View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2005. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <ostream>
#include <boost/parameter/keyword.hpp>
namespace graphs
{
BOOST_PARAMETER_KEYWORD(tag, graph) // Note: no semicolon
BOOST_PARAMETER_KEYWORD(tag, visitor)
BOOST_PARAMETER_KEYWORD(tag, root_vertex)
BOOST_PARAMETER_KEYWORD(tag, index_map)
BOOST_PARAMETER_KEYWORD(tag, color_map)
}
namespace graphs { namespace core
{
template <class ArgumentPack>
void depth_first_search(ArgumentPack const& args)
{
std::cout << "graph:\t" << args[graph] << std::endl;
std::cout << "visitor:\t" << args[visitor] << std::endl;
std::cout << "root_vertex:\t" << args[root_vertex] << std::endl;
std::cout << "index_map:\t" << args[index_map] << std::endl;
std::cout << "color_map:\t" << args[color_map] << std::endl;
}
}} // graphs::core
int main()
{
using namespace graphs;
core::depth_first_search((
graph = 'G', visitor = 2, root_vertex = 3.5,
index_map = "hello, world", color_map = false));
return 0;
}

75
test/unnamed.cpp Executable file
View File

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

30
test/unwrap_cv_reference.cpp Executable file
View File

@@ -0,0 +1,30 @@
// Copyright David Abrahams 2005. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/ref.hpp>
#include <boost/type_traits/is_same.hpp>
namespace test
{
using namespace boost::parameter::aux;
using namespace boost;
struct foo {};
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int>::type,int>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const>::type,int const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int volatile>::type,int volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const volatile>::type,int const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const>::type,foo const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo volatile>::type,foo volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const volatile>::type,foo const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> >::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> volatile>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const volatile>::type,foo>));
}