Compare commits

...

6 Commits

Author SHA1 Message Date
Beman Dawes
46d5bb0538 Create branches/filesystem-v3 for v2 removal
[SVN r77385]
2012-03-18 20:54:17 +00:00
Lorenzo Caminiti
5825b6c329 Fixed test indentation and updated docs.
[SVN r77080]
2012-02-20 20:17:07 +00:00
Lorenzo Caminiti
54c78121c2 Updated ScopeExit "world" tests making person a struct instead of a class.
Added a code comment to Utility/IdentityType tmp_assert test.

[SVN r77071]
2012-02-18 19:29:35 +00:00
Lorenzo Caminiti
2891cb52d6 Added Boost.Utility/IdentityType and Boost.Functional/OverloadedFunction to status/Jamfile.v2 list of regression tests.
Updated Boost.ScopeExit documentation.

[SVN r77059]
2012-02-17 21:02:00 +00:00
Daryle Walker
0db9276e8c Fixed (hopefully) conflict between boost::base_from_member's C++11 constructor template and the automatically defined non-template copy- and/or move-constructors.
[SVN r77046]
2012-02-17 01:55:33 +00:00
Lorenzo Caminiti
d6cb9a9176 Fixed a bug in BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST: a typo VOId -> VOID.
Fixed a bug in scope_exit.hpp: An extra trailing \ in a macro definition (compiled only when BOOST_NO_VARIADIC_MACROS is defined).
Renamed LocalFunction and ScopeExit tests and examples from _err to _error.
Updated LocalFunction docs.

[SVN r77042]
2012-02-16 18:24:34 +00:00
10 changed files with 178 additions and 102 deletions

View File

@@ -174,16 +174,18 @@ value of zero if it is omitted. The class template has a protected
data member called <var>member</var> that the derived class can use data member called <var>member</var> that the derived class can use
for later base classes (or itself).</p> for later base classes (or itself).</p>
<p>If the variadic template arguments and r-value reference features of C++2011 <p>If the appropriate features of C++2011 are present, there will be a single
are present, there will be a single constructor template. It implements constructor template. It implements &quot;perfect forwarding&quot; to the best
&quot;perfect forwarding&quot; to the best constructor call of constructor call of <code>member</code> (if any). The constructor template is
<code>member</code> (if any). The constructor template is marked both marked both <code>constexpr</code> and <code>explicit</code>. The former will
<code>constexpr</code> and <code>explicit</code>. The former will be ignored be ignored if the corresponding inner constructor call (of <code>member</code>)
if the corresponding inner constructor call (of <code>member</code>) does not does not have the marker. The latter binds the other way; always taking
have the marker. The latter binds the other way; always taking effect, even effect, even when the inner constructor call does not have the marker. The
when the inner constructor call does not have the marker. The constructor constructor template propagates the <code>noexcept</code> status of the inner
template propagates the <code>noexcept</code> status of the inner constructor constructor call. (The constructor template has a trailing parameter with a
call.</p> default value that disables the template when its signature is too close to the
signatures of the automatically-defined non-template copy- and/or
move-constructors of <code>base_from_member</code>.)</p>
<p>On earlier-standard compilers, there is a default constructor and several <p>On earlier-standard compilers, there is a default constructor and several
constructor member templates. These constructor templates can take as many constructor member templates. These constructor templates can take as many
@@ -385,7 +387,7 @@ a constructor call but <code>std::nullptr_t</code> cannot.)</p>
<hr> <hr>
<p>Revised: 11 February 2012</p> <p>Revised: 16 February 2012</p>
<p>Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and distribution <p>Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and distribution
are subject to the Boost Software License, Version 1.0. (See accompanying are subject to the Boost Software License, Version 1.0. (See accompanying

View File

@@ -7,13 +7,14 @@
This library allows to wrap type expressions within round parenthesis so they This library allows to wrap type expressions within round parenthesis so they
can be passed to macros even when they contain commas. can be passed to macros even when they contain commas.
</p><div class="section boost_utility_identitytype_motivation" title="Motivation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.motivation"></a><a class="link" href="#boost_utility_identitytype.motivation" title="Motivation">Motivation</a></h2></div></div></div><p> </p><div class="section boost_utility_identitytype_motivation" title="Motivation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.motivation"></a><a class="link" href="#boost_utility_identitytype.motivation" title="Motivation">Motivation</a></h2></div></div></div><p>
Consider the following macro which declares a variable named <code class="computeroutput"><span class="identifier">var</span></code><span class="emphasis"><em>n</em></span> with the specified Consider the following macro which declares a variable named <code class="computeroutput"><span class="identifier">var</span></code><code class="literal"><span class="emphasis"><em>n</em></span></code>
<span class="emphasis"><em>type</em></span> (see also <a href="../../test/var_err.cpp" target="_top"><code class="literal">var_err.cpp</code></a>): with the specified <code class="literal"><span class="emphasis"><em>type</em></span></code> (see also
<a href="../../test/var_error.cpp" target="_top"><code class="literal">var_error.cpp</code></a>):
</p><p> </p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">var</span> <span class="error">#</span><span class="preprocessor"># n</span> </p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">var</span> <span class="error">#</span><span class="preprocessor"># n</span>
<span class="identifier">VAR</span><span class="special">(</span> <span class="keyword">int</span><span class="special">,</span> <span class="number">1</span> <span class="special">);</span> <span class="comment">// OK.</span> <span class="identifier">VAR</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// OK.</span>
<span class="identifier">VAR</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;,</span> <span class="number">2</span> <span class="special">);</span> <span class="comment">// Error.</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;,</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// Error.</span>
</pre><p> </pre><p>
</p><p> </p><p>
The first macro invocation works correctly declaring a variable named <code class="computeroutput"><span class="identifier">var1</span></code> of type <code class="computeroutput"><span class="keyword">int</span></code>. The first macro invocation works correctly declaring a variable named <code class="computeroutput"><span class="identifier">var1</span></code> of type <code class="computeroutput"><span class="keyword">int</span></code>.
@@ -45,7 +46,7 @@
the type expression with the commas outside the macro (see also <a href="../../test/var.cpp" target="_top"><code class="literal">var.cpp</code></a>): the type expression with the commas outside the macro (see also <a href="../../test/var.cpp" target="_top"><code class="literal">var.cpp</code></a>):
</p><p> </p><p>
</p><pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">map_type</span><span class="special">;</span> </p><pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">map_type</span><span class="special">;</span>
<span class="identifier">VAR</span><span class="special">(</span> <span class="identifier">map_type</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span> <span class="comment">// OK.</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">map_type</span><span class="special">,</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// OK.</span>
</pre><p> </pre><p>
</p><p> </p><p>
When this is not possible or desired (e.g., see the function template <code class="computeroutput"><span class="identifier">f</span></code> in the section below), the library header When this is not possible or desired (e.g., see the function template <code class="computeroutput"><span class="identifier">f</span></code> in the section below), the library header
@@ -56,7 +57,7 @@
</p><p> </p><p>
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">identity_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> </p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">identity_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="identifier">VAR</span><span class="special">(</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)),</span> <span class="number">4</span> <span class="special">);</span> <span class="comment">// OK.</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)),</span> <span class="number">4</span><span class="special">);</span> <span class="comment">// OK.</span>
</pre><p> </pre><p>
</p><p> </p><p>
This macro expands to an expression that evaluates (at compile-time) to the This macro expands to an expression that evaluates (at compile-time) to the
@@ -71,14 +72,15 @@
</p></div><div class="section boost_utility_identitytype_templates" title="Templates"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.templates"></a><a class="link" href="#boost_utility_identitytype.templates" title="Templates">Templates</a></h2></div></div></div><p> </p></div><div class="section boost_utility_identitytype_templates" title="Templates"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.templates"></a><a class="link" href="#boost_utility_identitytype.templates" title="Templates">Templates</a></h2></div></div></div><p>
This macro must be prefixed by <code class="computeroutput"><span class="keyword">typename</span></code> This macro must be prefixed by <code class="computeroutput"><span class="keyword">typename</span></code>
when used within templates. For example, let's program a macro that declares when used within templates. For example, let's program a macro that declares
a function parameter named <code class="computeroutput"><span class="identifier">arg</span></code><span class="emphasis"><em>n</em></span> a function parameter named <code class="computeroutput"><span class="identifier">arg</span></code><code class="literal"><span class="emphasis"><em>n</em></span></code>
with the specified <span class="emphasis"><em>type</em></span> (see also <a href="../../test/template.cpp" target="_top"><code class="literal">template.cpp</code></a>): with the specified <code class="literal"><span class="emphasis"><em>type</em></span></code> (see also
<a href="../../test/template.cpp" target="_top"><code class="literal">template.cpp</code></a>):
</p><p> </p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ARG</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">arg</span> <span class="error">#</span><span class="preprocessor"># n</span> </p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ARG</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">arg</span> <span class="error">#</span><span class="preprocessor"># n</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span> <span class="comment">// Prefix macro with `typename` in templates.</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span> <span class="comment">// Prefix macro with `typename` in templates.</span>
<span class="identifier">ARG</span><span class="special">(</span> <span class="keyword">typename</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;)),</span> <span class="number">1</span> <span class="special">)</span> <span class="identifier">ARG</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;)),</span> <span class="number">1</span><span class="special">)</span>
<span class="special">)</span> <span class="special">{</span> <span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span> <span class="special">}</span>
@@ -87,20 +89,20 @@
</p><pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">;</span> </p><pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="char">'a'</span><span class="special">;</span> <span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="char">'a'</span><span class="special">;</span>
<span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK.</span> <span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK...</span>
<span class="comment">// f(a); // But error.</span> <span class="comment">// f(a); // ... but error.</span>
</pre><p> </pre><p>
</p><p> </p><p>
However, note that the template parameter type <code class="computeroutput"><span class="keyword">char</span></code> However, note that the template parameter <code class="computeroutput"><span class="keyword">char</span></code>
must be explicitly specified when invoking the function <code class="computeroutput"><span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">)</span></code>. In fact, must be manually specified when invoking the function <code class="computeroutput"><span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">)</span></code>. In fact,
when the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> when the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
macro is used to wrap a function template parameter, the template parameter macro is used to wrap a function template parameter, the template parameter
can no longer be implicitly determined by the compiler form the function call can no longer be automatically deduced by the compiler form the function call
as in <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code>. (This as in <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code>. <sup>[<a name="boost_utility_identitytype.templates.f0" href="#ftn.boost_utility_identitytype.templates.f0" class="footnote">2</a>]</sup> (This limitation does not apply to class templates because class
limitation does not apply to class templates because class template parameters template parameters must always be explicitly specified.) In other words, without
must always be explicitly specified.) In other words, without using the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro, C++ would using the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
normally be able to implicitly deduce the function template parameter as shown macro, C++ would normally be able to automatically deduce the function template
below: parameter as shown below:
</p><p> </p><p>
</p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">g</span><span class="special">(</span> <span class="keyword">void</span> <span class="identifier">g</span><span class="special">(</span>
@@ -110,14 +112,14 @@
<span class="special">}</span> <span class="special">}</span>
</pre><p> </pre><p>
</p><p> </p><p>
</p><pre class="programlisting"><span class="identifier">g</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK.</span> </p><pre class="programlisting"><span class="identifier">g</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK...</span>
<span class="identifier">g</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// Also OK.</span> <span class="identifier">g</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// ... and also OK.</span>
</pre><p> </pre><p>
</p></div><div class="section boost_utility_identitytype_abstract_types" title="Abstract Types"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.abstract_types"></a><a class="link" href="#boost_utility_identitytype.abstract_types" title="Abstract Types">Abstract Types</a></h2></div></div></div><p> </p></div><div class="section boost_utility_identitytype_abstract_types" title="Abstract Types"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.abstract_types"></a><a class="link" href="#boost_utility_identitytype.abstract_types" title="Abstract Types">Abstract Types</a></h2></div></div></div><p>
On some compilers (e.g., GCC), using this macro on abstract types (i.e., a On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes
class with one or more pure virtual functions) generates a compiler error. with one or more pure virtual functions) generates a compiler error. This can
This can be worked around by manipulating the type adding and removing a reference be worked around by manipulating the type adding and removing a reference to
to it. it.
</p><p> </p><p>
Let's program a macro that performs a static assertion on a <a href="http://en.wikipedia.org/wiki/Template_metaprogramming" target="_top">Template Let's program a macro that performs a static assertion on a <a href="http://en.wikipedia.org/wiki/Template_metaprogramming" target="_top">Template
Meta-Programming</a> (TMP) meta-function (similarly to Boost.MPL <a href="http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html" target="_top"><code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code></a>). The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro can be used Meta-Programming</a> (TMP) meta-function (similarly to Boost.MPL <a href="http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html" target="_top"><code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code></a>). The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro can be used
@@ -132,7 +134,7 @@
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">b</span><span class="special">&gt;</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">b</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">abstract</span> <span class="special">{</span> <span class="keyword">struct</span> <span class="identifier">abstract</span> <span class="special">{</span>
<span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// Pure virtual function.</span>
<span class="special">};</span> <span class="special">};</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span>
@@ -147,29 +149,32 @@
</pre><p> </pre><p>
</p></div><div class="section boost_utility_identitytype_annex__usage" title="Annex: Usage"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__usage"></a><a class="link" href="#boost_utility_identitytype.annex__usage" title="Annex: Usage">Annex: Usage</a></h2></div></div></div><p> </p></div><div class="section boost_utility_identitytype_annex__usage" title="Annex: Usage"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__usage"></a><a class="link" href="#boost_utility_identitytype.annex__usage" title="Annex: Usage">Annex: Usage</a></h2></div></div></div><p>
The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro
can be used either in the call of the user-defined macro (as shown by the examples can be used either when calling a user-defined macro (as shown by the examples
so far), or internally to the definition of the user macro. When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> is used internally, so far), or internally in the definition of a user-defined macro (as shown
the call of the user macro will only have to specify the extra parenthesis below). When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
(see also <a href="../../test/tmp_assert.cpp" target="_top"><code class="literal">tmp_assert.cpp</code></a>): is used in the user macro definition, the call of the user macro will only
have to specify the extra parenthesis (see also <a href="../../test/tmp_assert.cpp" target="_top"><code class="literal">tmp_assert.cpp</code></a>):
</p><p> </p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT_PAREN</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)</span> <span class="special">\</span> </p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT_PAREN</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)</span> <span class="special">\</span>
<span class="comment">/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */</span> <span class="special">\</span> <span class="comment">/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */</span> <span class="special">\</span>
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)::</span><span class="identifier">value</span><span class="special">)</span> <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)::</span><span class="identifier">value</span><span class="special">)</span>
<span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;</span> <span class="special">));</span> <span class="comment">// Specify only extra parenthesis `((...))`.</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;))</span> <span class="special">);</span> <span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;));</span>
<span class="comment">// Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;)));</span>
</pre><p> </pre><p>
</p><p> </p><p>
However, note that the user will <span class="emphasis"><em>always</em></span> have to specify However, note that the user will <span class="emphasis"><em>always</em></span> have to specify
the extra parenthesis even when the macro parameters contain no comma: the extra parenthesis even when the macro parameters contain no comma:
</p><p> </p><p>
</p><pre class="programlisting"><span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;</span> <span class="special">));</span> <span class="comment">// Always extra `()`.</span> </p><pre class="programlisting"><span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;));</span> <span class="comment">// Always extra `((...))`.</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;</span> <span class="special">);</span> <span class="comment">// No extra `()` and no macro.</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;);</span> <span class="comment">// No extra `((...))` and no macro.</span>
</pre><p> </pre><p>
</p><p> </p><p>
In some cases, using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> In some cases, using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
internally might provide the best syntax for the user. For example, this is within the user macro definition might provide the best syntax for the user.
the case for <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code> For example, this is the case for <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code>
because the majority of template meta-programming expressions contain unwrapped because the majority of template meta-programming expressions contain unwrapped
commas so it is less confusing for the user to always specify the extra parenthesis commas so it is less confusing for the user to always specify the extra parenthesis
<code class="computeroutput"><span class="special">((...))</span></code> instead of using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>: <code class="computeroutput"><span class="special">((...))</span></code> instead of using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>:
@@ -181,22 +186,21 @@
<span class="special">));</span> <span class="special">));</span>
</pre><p> </pre><p>
However, in other situations it might be preferable to not require the extra However, in other situations it might be preferable to not require the extra
parenthesis in common cases and handle commas as special cases using the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>. For example, this parenthesis in the common cases and handle commas as special cases using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>. For example, this
is the case for <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span></code> is the case for <a href="http://www.boost.org/libs/local_function" target="_top"><code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span></code></a> for which always
for which always requiring the extra parenthesis <code class="computeroutput"><span class="special">((...))</span></code> requiring the extra parenthesis <code class="computeroutput"><span class="special">((...))</span></code>
around the types would lead to an unnatural syntax for the local function parameter around the types would lead to an unnatural syntax for the local function signature:
types:
</p><pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">// Unnatural syntax.</span> </p><pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">// Unnatural syntax.</span>
<span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span>
<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span> <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
</pre><p> </pre><p>
Instead requiring the user to specify <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> Instead requiring the user to specify <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
when needed allows for the more natural syntax <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> only when needed allows for the more natural syntax <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span>
<span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span></code> in the common cases when the parameter types <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span></code> in the common cases when the parameter types
contain no comma. contain no comma.
</p></div><div class="section boost_utility_identitytype_annex__implementation" title="Annex: Implementation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__implementation"></a><a class="link" href="#boost_utility_identitytype.annex__implementation" title="Annex: Implementation">Annex: </p></div><div class="section boost_utility_identitytype_annex__implementation" title="Annex: Implementation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__implementation"></a><a class="link" href="#boost_utility_identitytype.annex__implementation" title="Annex: Implementation">Annex:
Implementation</a></h2></div></div></div><p> Implementation</a></h2></div></div></div><p>
The implementation of this library macro is equivalent to the following: <sup>[<a name="boost_utility_identitytype.annex__implementation.f0" href="#ftn.boost_utility_identitytype.annex__implementation.f0" class="footnote">2</a>]</sup> The implementation of this library macro is equivalent to the following: <sup>[<a name="boost_utility_identitytype.annex__implementation.f0" href="#ftn.boost_utility_identitytype.annex__implementation.f0" class="footnote">3</a>]</sup>
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">function_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> </p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">function_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_type</span><span class="special">)</span> <span class="special">\</span> <span class="preprocessor">#define</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_type</span><span class="special">)</span> <span class="special">\</span>
@@ -204,24 +208,29 @@
</pre><p> </pre><p>
Essentially, the type is wrapped between round parenthesis <code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> Essentially, the type is wrapped between round parenthesis <code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span>
<span class="keyword">char</span><span class="special">&gt;)</span></code> <span class="keyword">char</span><span class="special">&gt;)</span></code>
so it can be passed as a macro parameter even if it contain commas. Then the so it can be passed as a single macro parameter even if it contains commas.
parenthesized type is transformed into the type of a function returning <code class="computeroutput"><span class="keyword">void</span></code> and with the specified type as the type Then the parenthesized type is transformed into the type of a function returning
of the first and only argument <code class="computeroutput"><span class="keyword">void</span> <code class="computeroutput"><span class="keyword">void</span></code> and with the specified type
as the type of the first and only argument <code class="computeroutput"><span class="keyword">void</span>
<span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)</span></code>. Finally, the type of the first argument <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)</span></code>. Finally, the type of the first argument
<code class="computeroutput"><span class="identifier">arg1_type</span></code> is extracted therefore <code class="computeroutput"><span class="identifier">arg1_type</span></code> is extracted at compile-time
obtaining the original type from the parenthesized type (effectively stripping using the <code class="computeroutput"><span class="identifier">function_traits</span></code> meta-function
the parenthesis from around the type). therefore obtaining the original type from the parenthesized type (effectively
stripping the extra parenthesis from around the specified type).
</p></div><div class="section reference" title="Reference"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reference"></a>Reference</h2></div></div></div><div class="section header_boost_utility_identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;"><div class="titlepage"><div><div><h3 class="title"><a name="header.boost.utility.identity_type_hpp"></a>Header &lt;<a href="../../../../../boost/utility/identity_type.hpp" target="_top">boost/utility/identity_type.hpp</a>&gt;</h3></div></div></div><p>Wrap type expressions with round parenthesis so they can be passed to macros even if they contain commas. </p><pre class="synopsis"> </p></div><div class="section reference" title="Reference"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reference"></a>Reference</h2></div></div></div><div class="section header_boost_utility_identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;"><div class="titlepage"><div><div><h3 class="title"><a name="header.boost.utility.identity_type_hpp"></a>Header &lt;<a href="../../../../../boost/utility/identity_type.hpp" target="_top">boost/utility/identity_type.hpp</a>&gt;</h3></div></div></div><p>Wrap type expressions with round parenthesis so they can be passed to macros even if they contain commas. </p><pre class="synopsis">
<a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a>(parenthesized_type)</pre><div class="refentry" title="Macro BOOST_IDENTITY_TYPE"><a name="BOOST_IDENTITY_TYPE"></a><div class="titlepage"></div><div class="refnamediv"><h2><span class="refentrytitle">Macro BOOST_IDENTITY_TYPE</span></h2><p>BOOST_IDENTITY_TYPE — This macro allows to wrap the specified type expression within extra round parenthesis so the type can be passed as a single macro parameter even if it contains commas (not already wrapped within round parenthesis). </p></div><h2 class="refsynopsisdiv-title">Synopsis</h2><div class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="#header.boost.utility.identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;">boost/utility/identity_type.hpp</a>&gt; <a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a>(parenthesized_type)</pre><div class="refentry" title="Macro BOOST_IDENTITY_TYPE"><a name="BOOST_IDENTITY_TYPE"></a><div class="titlepage"></div><div class="refnamediv"><h2><span class="refentrytitle">Macro BOOST_IDENTITY_TYPE</span></h2><p>BOOST_IDENTITY_TYPE — This macro allows to wrap the specified type expression within extra round parenthesis so the type can be passed as a single macro parameter even if it contains commas (not already wrapped within round parenthesis). </p></div><h2 class="refsynopsisdiv-title">Synopsis</h2><div class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="#header.boost.utility.identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;">boost/utility/identity_type.hpp</a>&gt;
</span>BOOST_IDENTITY_TYPE(parenthesized_type)</pre></div><div class="refsect1" title="Description"><a name="id561548"></a><h2>Description</h2><p><span class="bold"><strong>Parameters:</strong></span> </p><div class="informaltable"><table class="table"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong><code class="computeroutput">parenthesized_type</code></strong></span></td><td>The type expression to be passed as macro parameter wrapped by a single set of round parenthesis <code class="computeroutput">(...)</code>. This type expression can contain an arbitrary number of commas. </td></tr></tbody></table></div><p> </span>BOOST_IDENTITY_TYPE(parenthesized_type)</pre></div><div class="refsect1" title="Description"><a name="id512092"></a><h2>Description</h2><p><span class="bold"><strong>Parameters:</strong></span> </p><div class="informaltable"><table class="table"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong><code class="computeroutput">parenthesized_type</code></strong></span></td><td>The type expression to be passed as macro parameter wrapped by a single set of round parenthesis <code class="computeroutput">(...)</code>. This type expression can contain an arbitrary number of commas. </td></tr></tbody></table></div><p>
</p><p>This macro works on any C++03 compiler (it does not require variadic macros).</p><p>This macro must be prefixed by <code class="computeroutput">typename</code> when used within templates. However, the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to be explicitly specified when calling the function template).</p><p>On some compilers (like GCC), using this macro on an abstract types requires to add and remove a reference to the type. </p></div></div></div></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.solution.f0" href="#boost_utility_identitytype.solution.f0" class="para">1</a>] </sup> </p><p>This macro works on any C++03 compiler (it does not require variadic macros).</p><p>This macro must be prefixed by <code class="computeroutput">typename</code> when used within templates. However, the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to be explicitly specified when calling the function template).</p><p>On some compilers (like GCC), using this macro on an abstract types requires to add and remove a reference to the type. </p></div></div></div></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.solution.f0" href="#boost_utility_identitytype.solution.f0" class="para">1</a>] </sup>
Using variadic macros, it would be possible to use a single set of parenthesis Using variadic macros, it would be possible to require a single set of extra
<code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span></code><span class="emphasis"><em>type</em></span><code class="computeroutput"><span class="special">)</span></code> instead of two <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span></code><span class="emphasis"><em>type</em></span><code class="computeroutput"><span class="special">))</span></code> parenthesis <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>type</em></span></code><code class="computeroutput"><span class="special">)</span></code> instead of two <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span></code><code class="literal"><span class="emphasis"><em>type</em></span></code><code class="computeroutput"><span class="special">))</span></code> but variadic macros are not part of C++03
but variadic macros are not part of C++03 (even if nowadays they are supported (even if nowadays they are supported by most modern compilers and they are
by most modern compilers and they are also part of C++11). also part of C++11).
</p></div><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.annex__implementation.f0" href="#boost_utility_identitytype.annex__implementation.f0" class="para">2</a>] </sup> </p></div><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.templates.f0" href="#boost_utility_identitytype.templates.f0" class="para">2</a>] </sup>
This is because the implementation of <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
wraps the specified type within a meta-function.
</p></div><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.annex__implementation.f0" href="#boost_utility_identitytype.annex__implementation.f0" class="para">3</a>] </sup>
There is absolutely no guarantee that the macro is actually implemented using There is absolutely no guarantee that the macro is actually implemented using
the code listed in this documentation. This code is for explanatory purposes the code listed in this documentation. This code is for explanatory purposes
only. only.

View File

@@ -21,16 +21,16 @@
This library allows to wrap type expressions within round parenthesis so they can be passed to macros even when they contain commas. This library allows to wrap type expressions within round parenthesis so they can be passed to macros even when they contain commas.
[import ../test/var_err.cpp] [import ../test/var_error.cpp]
[import ../test/var.cpp] [import ../test/var.cpp]
[import ../test/template.cpp] [import ../test/template.cpp]
[import ../test/tmp_assert.cpp] [import ../test/tmp_assert.cpp]
[section Motivation] [section Motivation]
Consider the following macro which declares a variable named `var`/n/ with the specified /type/ (see also [@../../test/var_err.cpp =var_err.cpp=]): Consider the following macro which declares a variable named `var`[^['n]] with the specified [^['type]] (see also [@../../test/var_error.cpp =var_error.cpp=]):
[var_err] [var_error]
The first macro invocation works correctly declaring a variable named `var1` of type `int`. The first macro invocation works correctly declaring a variable named `var1` of type `int`.
However, the second macro invocation fails generating a preprocessor error similar to the following: However, the second macro invocation fails generating a preprocessor error similar to the following:
@@ -68,7 +68,7 @@ In fact, a total of two sets of round parenthesis must be used: The parenthesis
This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (because it does not use [@http://en.wikipedia.org/wiki/Variadic_macro variadic macros]). This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (because it does not use [@http://en.wikipedia.org/wiki/Variadic_macro variadic macros]).
[footnote [footnote
Using variadic macros, it would be possible to use a single set of parenthesis `BOOST_IDENTITY_TYPE(`/type/`)` instead of two `BOOST_IDENTITY_TYPE((`/type/`))` but variadic macros are not part of C++03 (even if nowadays they are supported by most modern compilers and they are also part of C++11). Using variadic macros, it would be possible to require a single set of extra parenthesis `BOOST_IDENTITY_TYPE(`[^['type]]`)` instead of two `BOOST_IDENTITY_TYPE((`[^['type]]`))` but variadic macros are not part of C++03 (even if nowadays they are supported by most modern compilers and they are also part of C++11).
] ]
[endsect] [endsect]
@@ -76,15 +76,18 @@ Using variadic macros, it would be possible to use a single set of parenthesis `
[section Templates] [section Templates]
This macro must be prefixed by `typename` when used within templates. This macro must be prefixed by `typename` when used within templates.
For example, let's program a macro that declares a function parameter named `arg`/n/ with the specified /type/ (see also [@../../test/template.cpp =template.cpp=]): For example, let's program a macro that declares a function parameter named `arg`[^['n]] with the specified [^['type]] (see also [@../../test/template.cpp =template.cpp=]):
[template_f_decl] [template_f_decl]
[template_f_call] [template_f_call]
However, note that the template parameter type `char` must be explicitly specified when invoking the function `f<char>(a)`. However, note that the template parameter `char` must be manually specified when invoking the function `f<char>(a)`.
In fact, when the [macroref BOOST_IDENTITY_TYPE] macro is used to wrap a function template parameter, the template parameter can no longer be implicitly determined by the compiler form the function call as in `f(a)`. In fact, when the [macroref BOOST_IDENTITY_TYPE] macro is used to wrap a function template parameter, the template parameter can no longer be automatically deduced by the compiler form the function call as in `f(a)`.
[footnote
This is because the implementation of [macroref BOOST_IDENTITY_TYPE] wraps the specified type within a meta-function.
]
(This limitation does not apply to class templates because class template parameters must always be explicitly specified.) (This limitation does not apply to class templates because class template parameters must always be explicitly specified.)
In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ would normally be able to implicitly deduce the function template parameter as shown below: In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ would normally be able to automatically deduce the function template parameter as shown below:
[template_g_decl] [template_g_decl]
[template_g_call] [template_g_call]
@@ -93,7 +96,7 @@ In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ woul
[section Abstract Types] [section Abstract Types]
On some compilers (e.g., GCC), using this macro on abstract types (i.e., a class with one or more pure virtual functions) generates a compiler error. On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes with one or more pure virtual functions) generates a compiler error.
This can be worked around by manipulating the type adding and removing a reference to it. This can be worked around by manipulating the type adding and removing a reference to it.
Let's program a macro that performs a static assertion on a [@http://en.wikipedia.org/wiki/Template_metaprogramming Template Meta-Programming] (TMP) meta-function (similarly to Boost.MPL [@http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html `BOOST_MPL_ASSERT`]). Let's program a macro that performs a static assertion on a [@http://en.wikipedia.org/wiki/Template_metaprogramming Template Meta-Programming] (TMP) meta-function (similarly to Boost.MPL [@http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html `BOOST_MPL_ASSERT`]).
@@ -106,8 +109,8 @@ In this case, if the meta-function is an abstract type, it needs to be manipulat
[section Annex: Usage] [section Annex: Usage]
The [macroref BOOST_IDENTITY_TYPE] macro can be used either in the call of the user-defined macro (as shown by the examples so far), or internally to the definition of the user macro. The [macroref BOOST_IDENTITY_TYPE] macro can be used either when calling a user-defined macro (as shown by the examples so far), or internally in the definition of a user-defined macro (as shown below).
When [macroref BOOST_IDENTITY_TYPE] is used internally, the call of the user macro will only have to specify the extra parenthesis (see also [@../../test/tmp_assert.cpp =tmp_assert.cpp=]): When [macroref BOOST_IDENTITY_TYPE] is used in the user macro definition, the call of the user macro will only have to specify the extra parenthesis (see also [@../../test/tmp_assert.cpp =tmp_assert.cpp=]):
[tmp_assert_alternative] [tmp_assert_alternative]
@@ -115,7 +118,7 @@ However, note that the user will /always/ have to specify the extra parenthesis
[tmp_assert_alternative_always] [tmp_assert_alternative_always]
In some cases, using [macroref BOOST_IDENTITY_TYPE] internally might provide the best syntax for the user. In some cases, using [macroref BOOST_IDENTITY_TYPE] within the user macro definition might provide the best syntax for the user.
For example, this is the case for `BOOST_MPL_ASSERT` because the majority of template meta-programming expressions contain unwrapped commas so it is less confusing for the user to always specify the extra parenthesis `((...))` instead of using [macroref BOOST_IDENTITY_TYPE]: For example, this is the case for `BOOST_MPL_ASSERT` because the majority of template meta-programming expressions contain unwrapped commas so it is less confusing for the user to always specify the extra parenthesis `((...))` instead of using [macroref BOOST_IDENTITY_TYPE]:
BOOST_MPL_ASSERT(( // Natural syntax. BOOST_MPL_ASSERT(( // Natural syntax.
@@ -125,14 +128,14 @@ For example, this is the case for `BOOST_MPL_ASSERT` because the majority of tem
> >
)); ));
However, in other situations it might be preferable to not require the extra parenthesis in common cases and handle commas as special cases using the [macroref BOOST_IDENTITY_TYPE]. However, in other situations it might be preferable to not require the extra parenthesis in the common cases and handle commas as special cases using [macroref BOOST_IDENTITY_TYPE].
For example, this is the case for `BOOST_LOCAL_FUNCTION` for which always requiring the extra parenthesis `((...))` around the types would lead to an unnatural syntax for the local function parameter types: For example, this is the case for [@http://www.boost.org/libs/local_function `BOOST_LOCAL_FUNCTION`] for which always requiring the extra parenthesis `((...))` around the types would lead to an unnatural syntax for the local function signature:
int BOOST_LOCAL_FUNCTION( ((int&)) x, ((int&)) y ) { // Unnatural syntax. int BOOST_LOCAL_FUNCTION( ((int&)) x, ((int&)) y ) { // Unnatural syntax.
return x + y; return x + y;
} BOOST_LOCAL_FUNCTION_NAME(add) } BOOST_LOCAL_FUNCTION_NAME(add)
Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] when needed allows for the more natural syntax `BOOST_LOCAL_FUNCTION(int& x, int& y)` in the common cases when the parameter types contain no comma. Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when needed allows for the more natural syntax `BOOST_LOCAL_FUNCTION(int& x, int& y)` in the common cases when the parameter types contain no comma.
[endsect] [endsect]
@@ -149,9 +152,9 @@ This code is for explanatory purposes only.
#define BOOST_IDENTITY_TYPE(parenthesized_type) \ #define BOOST_IDENTITY_TYPE(parenthesized_type) \
boost::function_traits<void parenthesized_type>::arg1_type boost::function_traits<void parenthesized_type>::arg1_type
Essentially, the type is wrapped between round parenthesis `(std::map<int, char>)` so it can be passed as a macro parameter even if it contain commas. Essentially, the type is wrapped between round parenthesis `(std::map<int, char>)` so it can be passed as a single macro parameter even if it contains commas.
Then the parenthesized type is transformed into the type of a function returning `void` and with the specified type as the type of the first and only argument `void (std::map<int, char>)`. Then the parenthesized type is transformed into the type of a function returning `void` and with the specified type as the type of the first and only argument `void (std::map<int, char>)`.
Finally, the type of the first argument `arg1_type` is extracted therefore obtaining the original type from the parenthesized type (effectively stripping the parenthesis from around the type). Finally, the type of the first argument `arg1_type` is extracted at compile-time using the `function_traits` meta-function therefore obtaining the original type from the parenthesized type (effectively stripping the extra parenthesis from around the specified type).
[endsect] [endsect]

View File

@@ -7,7 +7,7 @@
import testing ; import testing ;
compile-fail var_err.cpp ; compile-fail var_error.cpp ;
run var.cpp ; run var.cpp ;
run template.cpp ; run template.cpp ;
run tmp_assert.cpp ; run tmp_assert.cpp ;

View File

@@ -14,7 +14,7 @@
template<typename T> template<typename T>
void f( // Prefix macro with `typename` in templates. void f( // Prefix macro with `typename` in templates.
ARG( typename BOOST_IDENTITY_TYPE((std::map<int, T>)), 1 ) ARG(typename BOOST_IDENTITY_TYPE((std::map<int, T>)), 1)
) { ) {
std::cout << arg1[0] << std::endl; std::cout << arg1[0] << std::endl;
} }
@@ -34,13 +34,13 @@ int main() {
std::map<int, char> a; std::map<int, char> a;
a[0] = 'a'; a[0] = 'a';
f<char>(a); // OK. f<char>(a); // OK...
// f(a); // But error. // f(a); // ... but error.
//] //]
//[template_g_call //[template_g_call
g<char>(a); // OK. g<char>(a); // OK...
g(a); // Also OK. g(a); // ... and also OK.
//] //]
return 0; return 0;

View File

@@ -19,7 +19,7 @@
template<typename T, bool b> template<typename T, bool b>
struct abstract { struct abstract {
static const bool value = b; static const bool value = b;
virtual void f(T const& x) = 0; virtual void f(T const& x) = 0; // Pure virtual function.
}; };
TMP_ASSERT( TMP_ASSERT(
@@ -38,13 +38,15 @@ TMP_ASSERT(
/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \ /* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value) BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
TMP_ASSERT_PAREN(( boost::is_const<std::map<int, char> const> )); // Specify only extra parenthesis `((...))`.
TMP_ASSERT( BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)) ); TMP_ASSERT_PAREN((boost::is_const<std::map<int, char> const>));
// Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.
TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)));
//] //]
//[tmp_assert_alternative_always //[tmp_assert_alternative_always
TMP_ASSERT_PAREN(( boost::is_const<int const> )); // Always extra `()`. TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
TMP_ASSERT( boost::is_const<int const> ); // No extra `()` and no macro. TMP_ASSERT(boost::is_const<int const>); // No extra `((...))` and no macro.
//] //]
int main() { return 0; } int main() { return 0; }

View File

@@ -9,17 +9,17 @@
#define VAR(type, n) type var ## n #define VAR(type, n) type var ## n
VAR( int, 1 ); // OK. VAR(int, 1); // OK.
//[var_typedef //[var_typedef
typedef std::map<int, char> map_type; typedef std::map<int, char> map_type;
VAR( map_type, 3 ); // OK. VAR(map_type, 3); // OK.
//] //]
//[var_ok //[var_ok
#include <boost/utility/identity_type.hpp> #include <boost/utility/identity_type.hpp>
VAR( BOOST_IDENTITY_TYPE((std::map<int, char>)), 4 ); // OK. VAR(BOOST_IDENTITY_TYPE((std::map<int, char>)), 4); // OK.
//] //]
int main() { return 0; } int main() { return 0; }

View File

@@ -7,11 +7,11 @@
#include <map> #include <map>
//[var_err //[var_error
#define VAR(type, n) type var ## n #define VAR(type, n) type var ## n
VAR( int, 1 ); // OK. VAR(int, 1); // OK.
VAR( std::map<int, char>, 2 ); // Error. VAR(std::map<int, char>, 2); // Error.
//] //]
int main() { return 0; } int main() { return 0; }

View File

@@ -15,6 +15,10 @@
#include <boost/preprocessor/repetition/enum_binary_params.hpp> #include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp> #include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
// Base-from-member arity configuration macro ------------------------------// // Base-from-member arity configuration macro ------------------------------//
@@ -54,6 +58,59 @@
namespace boost namespace boost
{ {
namespace detail
{
// Type-unmarking class template -------------------------------------------//
// Type-trait to get the raw type, i.e. the type without top-level reference nor
// cv-qualification, from a type expression. Mainly for function arguments, any
// reference part is stripped first.
// Contributed by Daryle Walker
template < typename T >
struct remove_cv_ref
{
typedef typename ::boost::remove_cv<typename
::boost::remove_reference<T>::type>::type type;
}; // boost::detail::remove_cv_ref
// Unmarked-type comparison class template ---------------------------------//
// Type-trait to check if two type expressions have the same raw type.
// Contributed by Daryle Walker, based on a work-around by Luc Danton
template < typename T, typename U >
struct is_related
: public ::boost::is_same<
typename ::boost::detail::remove_cv_ref<T>::type,
typename ::boost::detail::remove_cv_ref<U>::type >
{};
// Enable-if-on-unidentical-unmarked-type class template -------------------//
// Enable-if on the first two type expressions NOT having the same raw type.
// Contributed by Daryle Walker, based on a work-around by Luc Danton
#ifndef BOOST_NO_VARIADIC_TEMPLATES
template<typename ...T>
struct enable_if_unrelated
: public ::boost::enable_if_c<true>
{};
template<typename T, typename U, typename ...U2>
struct enable_if_unrelated<T, U, U2...>
: public ::boost::disable_if< ::boost::detail::is_related<T, U> >
{};
#endif
} // namespace boost::detail
// Base-from-member class template -----------------------------------------// // Base-from-member class template -----------------------------------------//
// Helper to initialize a base object so a derived class can use this // Helper to initialize a base object so a derived class can use this
@@ -69,8 +126,11 @@ class base_from_member
protected: protected:
MemberType member; MemberType member;
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL) #if !defined(BOOST_NO_RVALUE_REFERENCES) && \
template <typename ...T> !defined(BOOST_NO_VARIADIC_TEMPLATES) && \
!defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template <typename ...T, typename EnableIf = typename
::boost::detail::enable_if_unrelated<base_from_member, T...>::type>
explicit BOOST_CONSTEXPR base_from_member( T&& ...x ) explicit BOOST_CONSTEXPR base_from_member( T&& ...x )
BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType( BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType(
static_cast<T&&>(x)... )) ) // no std::is_nothrow_constructible... static_cast<T&&>(x)... )) ) // no std::is_nothrow_constructible...

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