mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 22:10:54 +02:00
Compare commits
7 Commits
boost-1.50
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
c7f99ec5b6 | ||
|
2a6cd0c9c4 | ||
|
5825b6c329 | ||
|
54c78121c2 | ||
|
2891cb52d6 | ||
|
0db9276e8c | ||
|
d6cb9a9176 |
@@ -129,6 +129,8 @@ particular member type does not need to concern itself with the integer.</p>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
#include <type_traits> <i>// exposition only</i>
|
||||
|
||||
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
||||
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
||||
#endif
|
||||
@@ -139,6 +141,11 @@ class boost::base_from_member
|
||||
protected:
|
||||
MemberType member;
|
||||
|
||||
#if <i>C++2011 is in use</i>
|
||||
template< typename ...T >
|
||||
explicit constexpr base_from_member( T&& ...x )
|
||||
noexcept( std::is_nothrow_constructible<MemberType, T...>::value );
|
||||
#else
|
||||
base_from_member();
|
||||
|
||||
template< typename T1 >
|
||||
@@ -154,6 +161,7 @@ protected:
|
||||
typename T10 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
|
||||
T8 x8, T9 x9, T10 x10 );
|
||||
#endif
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -166,13 +174,29 @@ 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
|
||||
for later base classes (or itself).</p>
|
||||
|
||||
<p>There is a default constructor and several constructor member
|
||||
templates. These constructor templates can take as many arguments
|
||||
(currently up to ten) as possible and pass them to a constructor of
|
||||
the data member. Since C++ does not allow any way to explicitly state
|
||||
<p>If the appropriate features of C++2011 are present, there will be a single
|
||||
constructor template. It implements "perfect forwarding" to the best
|
||||
constructor call of <code>member</code> (if any). The constructor template is
|
||||
marked both <code>constexpr</code> and <code>explicit</code>. The former will
|
||||
be ignored if the corresponding inner constructor call (of <code>member</code>)
|
||||
does not have the marker. The latter binds the other way; always taking
|
||||
effect, even when the inner constructor call does not have the marker. The
|
||||
constructor template propagates the <code>noexcept</code> status of the inner
|
||||
constructor call. (The constructor template has a trailing parameter with a
|
||||
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
|
||||
constructor member templates. These constructor templates can take as many
|
||||
arguments (currently up to ten) as possible and pass them to a constructor of
|
||||
the data member.</p>
|
||||
|
||||
<p>Since C++ does not allow any way to explicitly state
|
||||
the template parameters of a templated constructor, make sure that
|
||||
the arguments are already close as possible to the actual type used in
|
||||
the data member's desired constructor.</p>
|
||||
the data member's desired constructor. Explicit conversions may be
|
||||
necessary.</p>
|
||||
|
||||
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies
|
||||
the maximum argument length for the constructor templates. The constant
|
||||
@@ -180,7 +204,7 @@ may be overridden if more (or less) argument configurations are needed. The
|
||||
constant may be read for code that is expandable like the class template and
|
||||
needs to maintain the same maximum size. (Example code would be a class that
|
||||
uses this class template as a base class for a member with a flexible set of
|
||||
constructors.)</p>
|
||||
constructors.) This constant is ignored when C++2011 features are present.</p>
|
||||
|
||||
<h2><a name="usage">Usage</a></h2>
|
||||
|
||||
@@ -323,11 +347,14 @@ constructor argument for <code>pbase0_type</code> is converted from
|
||||
argument for <code>pbase2_type</code> is converted from <code>int</code>
|
||||
to <code>double</code>. The second constructor argument for
|
||||
<code>pbase3_type</code> is a special case of necessary conversion; all
|
||||
forms of the null-pointer literal in C++ also look like compile-time
|
||||
integral expressions, so C++ always interprets such code as an integer
|
||||
when it has overloads that can take either an integer or a pointer. The
|
||||
last conversion is necessary for the compiler to call a constructor form
|
||||
with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||
forms of the null-pointer literal in C++ (except <code>nullptr</code> from
|
||||
C++2011) also look like compile-time integral expressions, so C++ always
|
||||
interprets such code as an integer when it has overloads that can take either
|
||||
an integer or a pointer. The last conversion is necessary for the compiler to
|
||||
call a constructor form with the exact pointer type used in
|
||||
<code>switcher</code>'s constructor. (If C++2011's <code>nullptr</code> is
|
||||
used, it still needs a conversion if multiple pointer types can be accepted in
|
||||
a constructor call but <code>std::nullptr_t</code> cannot.)</p>
|
||||
|
||||
<h2><a name="credits">Credits</a></h2>
|
||||
|
||||
@@ -360,9 +387,9 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised: 28 August 2004</p>
|
||||
<p>Revised: 16 February 2012</p>
|
||||
|
||||
<p>Copyright 2001, 2003, 2004 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
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a
|
||||
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||
|
@@ -210,8 +210,10 @@ int main()
|
||||
comparible_UDT u;
|
||||
c1(u);
|
||||
call_traits_checker<int> c2;
|
||||
call_traits_checker<enum_UDT> c2b;
|
||||
int i = 2;
|
||||
c2(i);
|
||||
c2b(one);
|
||||
int* pi = &i;
|
||||
int a[2] = {1,2};
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
|
||||
@@ -292,7 +294,11 @@ int main()
|
||||
BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
|
||||
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
|
||||
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
|
||||
|
||||
// test enum:
|
||||
BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
|
||||
BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
|
||||
BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
|
||||
BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
[/
|
||||
/ Copyright (c) 2008 Howard Hinnant
|
||||
/ Copyright (c) 2009-20012 Vicente J. Botet Escriba
|
||||
/ Copyright (c) 2008 Beman Dawes
|
||||
/ Copyright (c) 2009-20010 Vicente J. Botet Escriba
|
||||
/
|
||||
/ 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)
|
||||
@@ -9,9 +10,11 @@
|
||||
[article Declval
|
||||
[quickbook 1.5]
|
||||
[authors [Hinnant, Howard]]
|
||||
[authors [Dawes, Beman]]
|
||||
[authors [Botet Escriba, Vicente J.]]
|
||||
[copyright 2008 Howard Hinnant]
|
||||
[copyright 2009-2012 Vicente J. Botet Escriba]
|
||||
[copyright 2008 Beman Dawes]
|
||||
[copyright 2009-2010 Vicente J. Botet Escriba]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -74,7 +77,7 @@ This extremely light-weight function is expected to be part of the daily tool-bo
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand
|
||||
typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -97,19 +100,5 @@ Declares a function template convert which only participates in overloading if t
|
||||
|
||||
[endsect]
|
||||
|
||||
[/===============]
|
||||
[section History]
|
||||
[/===============]
|
||||
|
||||
[heading boost 1.50]
|
||||
|
||||
Fixes:
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Declval</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.0">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
|
||||
<link rel="home" href="declval.html" title="Declval">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@@ -27,13 +27,17 @@
|
||||
<span class="firstname">Howard</span> <span class="surname">Hinnant</span>
|
||||
</h3></div>
|
||||
<div class="author"><h3 class="author">
|
||||
<span class="firstname">Beman</span> <span class="surname">Dawes</span>
|
||||
</h3></div>
|
||||
<div class="author"><h3 class="author">
|
||||
<span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span>
|
||||
</h3></div>
|
||||
</div></div>
|
||||
<div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div>
|
||||
<div><p class="copyright">Copyright © 2009 -2012 Vicente J. Botet Escriba</p></div>
|
||||
<div><p class="copyright">Copyright © 2008 Beman Dawes</p></div>
|
||||
<div><p class="copyright">Copyright © 2009, 2010 Vicente J. Botet Escriba</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="idp13449552"></a><p>
|
||||
<a name="id3354293"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
@@ -46,7 +50,6 @@
|
||||
<dl>
|
||||
<dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="declval.html#declval.reference">Reference </a></span></dt>
|
||||
<dt><span class="section"><a href="declval.html#declval.history">History</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section">
|
||||
@@ -119,7 +122,7 @@
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">()</span> <span class="identifier">noexcept</span><span class="special">;</span> <span class="comment">// as unevaluated operand
|
||||
<span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">//noexcept; // as unevaluated operand
|
||||
</span>
|
||||
<span class="special">}</span> <span class="comment">// namespace boost
|
||||
</span></pre>
|
||||
@@ -149,25 +152,9 @@
|
||||
if the type From can be explicitly converted to type To.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.history"></a><a class="link" href="declval.html#declval.history" title="History">History</a>
|
||||
</h2></div></div></div>
|
||||
<a name="declval.history.boost_1_50"></a><h4>
|
||||
<a name="idp13553216"></a>
|
||||
<a class="link" href="declval.html#declval.history.boost_1_50">boost 1.50</a>
|
||||
</h4>
|
||||
<p>
|
||||
Fixes:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
||||
<a href="http://svn.boost.org/trac/boost/ticket/6570" target="_top">#6570</a>
|
||||
Adding noexcept to boost::declval.
|
||||
</li></ul></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: May 28, 2012 at 18:59:06 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: April 06, 2011 at 20:06:10 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@@ -15,7 +15,7 @@ doxygen reference : ../../../../boost/utility/identity_type.hpp
|
||||
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
<doxygen:param>HIDE_UNDOC_CLASSES=YES
|
||||
<doxygen:param>ALIASES=" Params=\"<b>Parameters:</b> <table border="0">\" Param{2}=\"<tr><td><b><tt>\\1</tt></b></td><td>\\2</td></tr>\" EndParams=\"</table>\" Returns=\"<b>Returns:</b>\" Note=\"<b>Note:</b>\" Warning=\"<b>Warning:</b>\" See=\"<b>See:</b>\" RefSect{2}=\"\\xmlonly<link linkend='boost_utility_identitytype.\\1'>\\2</link>\\endxmlonly\" RefClass{1}=\"\\xmlonly<computeroutput><classname alt='\\1'>\\1</classname></computeroutput>\\endxmlonly\" RefFunc{1}=\"\\xmlonly<computeroutput><functionname alt='\\1'>\\1</functionname></computeroutput>\\endxmlonly\" RefMacro{1}=\"\\xmlonly<computeroutput><macroname alt='\\1'>\\1</macroname></computeroutput>\\endxmlonly\" "
|
||||
<doxygen:param>ALIASES=" Params=\"<b>Parameters:</b> <table border="0">\" Param{2}=\"<tr><td><b><tt>\\1</tt></b></td><td>\\2</td></tr>\" EndParams=\"</table>\" Returns=\"<b>Returns:</b>\" Note=\"<b>Note:</b>\" Warning=\"<b>Warning:</b>\" See=\"<b>See:</b>\" RefSect{1}=\"\\xmlonly<link linkend='boost_utility_identitytype.\\1'>\\1</link>\\endxmlonly\" RefSectId{2}=\"\\xmlonly<link linkend='boost_utility_identitytype.\\1'>\\2</link>\\endxmlonly\" RefClass{1}=\"\\xmlonly<computeroutput><classname alt='\\1'>\\1</classname></computeroutput>\\endxmlonly\" RefFunc{1}=\"\\xmlonly<computeroutput><functionname alt='\\1'>\\1</functionname></computeroutput>\\endxmlonly\" RefMacro{1}=\"\\xmlonly<computeroutput><macroname alt='\\1'>\\1</macroname></computeroutput>\\endxmlonly\" "
|
||||
;
|
||||
|
||||
# This target must be called "index" so to generate "index.html" file.
|
||||
|
@@ -2,10 +2,11 @@
|
||||
Caminiti</p></div><div><div class="legalnotice" title="Legal Notice"><a name="boost_utility_identitytype.legal"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0 (see accompanying
|
||||
file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p></div></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#boost_utility_identitytype.motivation">Motivation</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.solution">Solution</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.templates">Templates</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.abstract_types">Abstract Types</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__usage">Annex: Usage</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__implementation">Annex:
|
||||
</p></div></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#boost_utility_identitytype.motivation">Motivation</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.solution">Solution</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.templates">Templates</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.abstract_types">Abstract Types</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.compilers_and_platforms">Compilers
|
||||
and Platforms</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__usage">Annex: Usage</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__implementation">Annex:
|
||||
Implementation</a></span></dt><dt><span class="section"><a href="#reference">Reference</a></span></dt></dl></div><p>
|
||||
This library allows to wrap types within round parenthesis so they can always
|
||||
be passed as macro parameters.
|
||||
This library allows to wrap type expressions within round parenthesis so they
|
||||
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>
|
||||
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>
|
||||
with the specified <code class="literal"><span class="emphasis"><em>type</em></span></code> (see also
|
||||
@@ -36,23 +37,21 @@
|
||||
<code class="computeroutput"><span class="number">2</span></code>
|
||||
</li></ol></div><p>
|
||||
Note that, differently from the compiler, the preprocessor only recognizes
|
||||
round parenthesis <code class="computeroutput"><span class="special">()</span></code>. Angular
|
||||
<code class="computeroutput"><span class="special"><></span></code> and squared <code class="computeroutput"><span class="special">[]</span></code> parenthesis are not recognized by the preprocessor
|
||||
when parsing macro parameters.
|
||||
round parameters <code class="computeroutput"><span class="special">()</span></code>. Angular
|
||||
<code class="computeroutput"><span class="special"><></span></code> or squared <code class="computeroutput"><span class="special">[]</span></code> parenthesis are not used by the preprocessor
|
||||
when parsing the macro parameters.
|
||||
</p></div><div class="section boost_utility_identitytype_solution" title="Solution"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.solution"></a><a class="link" href="#boost_utility_identitytype.solution" title="Solution">Solution</a></h2></div></div></div><p>
|
||||
In some cases, it might be possible to workaround this issue by avoiding to
|
||||
pass the type expression to the macro all together. For example, in the case
|
||||
above a <code class="computeroutput"><span class="keyword">typedef</span></code> could have been
|
||||
used to specify 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>):
|
||||
pass the type expression to the macro all together. For example, in some cases
|
||||
a <code class="computeroutput"><span class="keyword">typedef</span></code> can be used to specify
|
||||
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><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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">></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>
|
||||
</pre><p>
|
||||
</p><p>
|
||||
When this is neither possible nor desired (e.g., see the function template
|
||||
<code class="computeroutput"><span class="identifier">f</span></code> in the section below), this
|
||||
library header <code class="computeroutput"><a class="link" href="#header.boost.utility.identity_type_hpp" title="Header <boost/utility/identity_type.hpp>">boost/utility/identity_type.hpp</a></code>
|
||||
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
|
||||
<code class="computeroutput"><a class="link" href="#header.boost.utility.identity_type_hpp" title="Header <boost/utility/identity_type.hpp>">boost/utility/identity_type.hpp</a></code>
|
||||
defines a macro <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
|
||||
which can be used to workaround the issue while keeping the type expression
|
||||
as one of the macro parameters (see also <a href="../../test/var.cpp" target="_top"><code class="literal">var.cpp</code></a>).
|
||||
@@ -62,21 +61,15 @@
|
||||
<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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>)),</span> <span class="number">4</span><span class="special">);</span> <span class="comment">// OK.</span>
|
||||
</pre><p>
|
||||
</p><p>
|
||||
The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro
|
||||
expands to an expression that evaluates (at compile-time) to the specified
|
||||
type. The specified type is never split into multiple macro parameters because
|
||||
it is always wrapped by a set of extra round parenthesis <code class="computeroutput"><span class="special">()</span></code>.
|
||||
In fact, a total of two sets of round parenthesis must be used: The parenthesis
|
||||
to invoke the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(...)</span></code> plus the inner parenthesis to wrap the
|
||||
This macro expands to an expression that evaluates (at compile-time) to the
|
||||
specified type. The specified type is never split into multiple macro parameters
|
||||
because it is always wrapped by a set of extra round parenthesis <code class="computeroutput"><span class="special">()</span></code>. In fact, a total of two sets of round parenthesis
|
||||
must be used: The parenthesis to invoke the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(...)</span></code> plus the inner parenthesis to wrap the
|
||||
type passed to the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((...))</span></code>.
|
||||
</p><p>
|
||||
This macro works on any <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
|
||||
compiler (and it does not use <a href="http://en.wikipedia.org/wiki/Variadic_macro" target="_top">variadic
|
||||
macros</a>). <sup>[<a name="boost_utility_identitytype.solution.f0" href="#ftn.boost_utility_identitytype.solution.f0" class="footnote">1</a>]</sup> The authors originally developed and tested this library using
|
||||
GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled
|
||||
<code class="computeroutput"><span class="special">-</span><span class="identifier">std</span><span class="special">=</span><span class="identifier">c</span><span class="special">++</span><span class="number">0</span><span class="identifier">x</span></code>) on Cygwin
|
||||
and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. See the library <a href="http://www.boost.org/development/tests/release/developer/utility-identity_type.html" target="_top">regressions
|
||||
test results</a> for more information on supported compilers and platforms.
|
||||
compiler (because it does not use <a href="http://en.wikipedia.org/wiki/Variadic_macro" target="_top">variadic
|
||||
macros</a>). <sup>[<a name="boost_utility_identitytype.solution.f0" href="#ftn.boost_utility_identitytype.solution.f0" class="footnote">1</a>]</sup>
|
||||
</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>
|
||||
when used within templates. For example, let's program a macro that declares
|
||||
@@ -102,12 +95,11 @@
|
||||
</pre><p>
|
||||
</p><p>
|
||||
However, note that the template parameter <code class="computeroutput"><span class="keyword">char</span></code>
|
||||
must be manually specified when invoking the function as in <code class="computeroutput"><span class="identifier">f</span><span class="special"><</span><span class="keyword">char</span><span class="special">>(</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"><</span><span class="keyword">char</span><span class="special">>(</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>
|
||||
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 <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code> would
|
||||
have done. <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
|
||||
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
|
||||
template parameters 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 normally be able to automatically deduce the function template
|
||||
@@ -127,7 +119,8 @@
|
||||
</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., classes
|
||||
with one or more pure virtual functions) generates a compiler error. This can
|
||||
be avoided by manipulating the type adding and removing a reference to it.
|
||||
be worked around by manipulating the type adding and removing a reference to
|
||||
it.
|
||||
</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
|
||||
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
|
||||
@@ -155,13 +148,25 @@
|
||||
<span class="special">>::</span><span class="identifier">type</span>
|
||||
<span class="special">);</span>
|
||||
</pre><p>
|
||||
</p></div><div class="section boost_utility_identitytype_compilers_and_platforms" title="Compilers and Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.compilers_and_platforms"></a><a class="link" href="#boost_utility_identitytype.compilers_and_platforms" title="Compilers and Platforms">Compilers
|
||||
and Platforms</a></h2></div></div></div><p>
|
||||
The authors originally developed and tested the library on:
|
||||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||||
GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features
|
||||
enabled <code class="computeroutput"><span class="special">-</span><span class="identifier">std</span><span class="special">=</span><span class="identifier">c</span><span class="special">++</span><span class="number">0</span><span class="identifier">x</span></code>) on
|
||||
Cygwin.
|
||||
</li><li class="listitem">
|
||||
Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
|
||||
</li></ol></div><p>
|
||||
See the library <a href="http://www.boost.org/development/tests/release/developer/utility-identity_type.html" target="_top">regressions
|
||||
test results</a> for detailed information on supported compilers and platforms.
|
||||
</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
|
||||
can be used either when calling a user-defined macro (as shown by the examples
|
||||
so far), or internally when implementing a user-defined macro (as shown below).
|
||||
When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> is
|
||||
used in the implementation of the user-defined macro, the caller of the user
|
||||
macro will have to specify the extra parenthesis (see also <a href="../../test/paren.cpp" target="_top"><code class="literal">paren.cpp</code></a>):
|
||||
so far), or internally in the definition of a user-defined macro (as shown
|
||||
below). When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
|
||||
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/paren.cpp" target="_top"><code class="literal">paren.cpp</code></a>):
|
||||
</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>
|
||||
<span class="comment">/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */</span> <span class="special">\</span>
|
||||
@@ -177,7 +182,7 @@
|
||||
<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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">></span> <span class="keyword">const</span><span class="special">>)));</span>
|
||||
</pre><p>
|
||||
</p><p>
|
||||
However, note that the caller 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:
|
||||
</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"><</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">>));</span> <span class="comment">// Always extra `((...))`.</span>
|
||||
@@ -186,8 +191,8 @@
|
||||
</pre><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 the implementation of the user-defined macro might provide the best syntax
|
||||
for the caller. For example, this is the case for <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code>
|
||||
within the user macro definition might provide the best syntax for the user.
|
||||
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
|
||||
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>:
|
||||
@@ -210,9 +215,7 @@
|
||||
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>
|
||||
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">&</span>
|
||||
<span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">y</span><span class="special">)</span></code> in the common cases when the parameter types
|
||||
contain no comma (while still allowing to specify parameter types with commas
|
||||
as special cases using <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>))&</span>
|
||||
<span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">y</span><span class="special">)</span></code>).
|
||||
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:
|
||||
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">3</a>]</sup>
|
||||
@@ -236,8 +239,8 @@
|
||||
|
||||
<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: <<a class="link" href="#header.boost.utility.identity_type_hpp" title="Header <boost/utility/identity_type.hpp>">boost/utility/identity_type.hpp</a>>
|
||||
|
||||
</span>BOOST_IDENTITY_TYPE(parenthesized_type)</pre></div><div class="refsect1" title="Description"><a name="id554262"></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 use variadic macros).</p><p>This macro must be prefixed by <code class="computeroutput">typename</code> when used within templates. Note that 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 abstract types requires to add and remove a reference to the specified 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>
|
||||
</span>BOOST_IDENTITY_TYPE(parenthesized_type)</pre></div><div class="refsect1" title="Description"><a name="id558453"></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>
|
||||
Using variadic macros, it would be possible to require a single set of extra
|
||||
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
|
||||
(even if nowadays they are supported by most modern compilers and they are
|
||||
@@ -247,6 +250,6 @@
|
||||
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
|
||||
the code listed in this documentation. The listed code is for explanatory
|
||||
purposes only.
|
||||
the code listed in this documentation. This code is for explanatory purposes
|
||||
only.
|
||||
</p></div></div></div></body></html>
|
||||
|
@@ -19,7 +19,7 @@
|
||||
[category Utilities]
|
||||
]
|
||||
|
||||
This library allows to wrap types within round parenthesis so they can always be passed as macro parameters.
|
||||
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_error.cpp]
|
||||
[import ../test/var.cpp]
|
||||
@@ -47,32 +47,30 @@ The preprocessor interprets that unwrapped comma as a separation between macro p
|
||||
# `char>`
|
||||
# `2`
|
||||
|
||||
Note that, differently from the compiler, the preprocessor only recognizes round parenthesis `()`.
|
||||
Angular `<>` and squared `[]` parenthesis are not recognized by the preprocessor when parsing macro parameters.
|
||||
Note that, differently from the compiler, the preprocessor only recognizes round parameters `()`.
|
||||
Angular `<>` or squared `[]` parenthesis are not used by the preprocessor when parsing the macro parameters.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Solution]
|
||||
|
||||
In some cases, it might be possible to workaround this issue by avoiding to pass the type expression to the macro all together.
|
||||
For example, in the case above a `typedef` could have been used to specify the type expression with the commas outside the macro (see also [@../../test/var.cpp =var.cpp=]):
|
||||
For example, in some cases a `typedef` can be used to specify the type expression with the commas outside the macro (see also [@../../test/var.cpp =var.cpp=]):
|
||||
|
||||
[var_typedef]
|
||||
|
||||
When this is neither possible nor desired (e.g., see the function template `f` in the section below), this library header [headerref boost/utility/identity_type.hpp] defines a macro [macroref BOOST_IDENTITY_TYPE] which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also [@../../test/var.cpp =var.cpp=]).
|
||||
When this is not possible or desired (e.g., see the function template `f` in the section below), the library header [headerref boost/utility/identity_type.hpp] defines a macro [macroref BOOST_IDENTITY_TYPE] which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also [@../../test/var.cpp =var.cpp=]).
|
||||
|
||||
[var_ok]
|
||||
|
||||
The [macroref BOOST_IDENTITY_TYPE] macro expands to an expression that evaluates (at compile-time) to the specified type.
|
||||
This macro expands to an expression that evaluates (at compile-time) to the specified type.
|
||||
The specified type is never split into multiple macro parameters because it is always wrapped by a set of extra round parenthesis `()`.
|
||||
In fact, a total of two sets of round parenthesis must be used: The parenthesis to invoke the macro `BOOST_IDENTITY_TYPE(...)` plus the inner parenthesis to wrap the type passed to the macro `BOOST_IDENTITY_TYPE((...))`.
|
||||
|
||||
This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (and 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
|
||||
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).
|
||||
]
|
||||
The authors originally developed and tested this library using GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
|
||||
See the library [@http://www.boost.org/development/tests/release/developer/utility-identity_type.html regressions test results] for more information on supported compilers and platforms.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -84,8 +82,8 @@ For example, let's program a macro that declares a function parameter named `arg
|
||||
[template_f_decl]
|
||||
[template_f_call]
|
||||
|
||||
However, note that the template parameter `char` must be manually specified when invoking the function as in `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 automatically deduced by the compiler form the function call as `f(a)` would have done.
|
||||
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 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.
|
||||
]
|
||||
@@ -100,7 +98,7 @@ In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ woul
|
||||
[section Abstract Types]
|
||||
|
||||
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 avoided 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`]).
|
||||
The [macroref BOOST_IDENTITY_TYPE] macro can be used to pass a meta-function with multiple template parameters to the assert macro (so to handle the commas separating the template parameters).
|
||||
@@ -110,18 +108,29 @@ In this case, if the meta-function is an abstract type, it needs to be manipulat
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Compilers and Platforms]
|
||||
|
||||
The authors originally developed and tested the library on:
|
||||
|
||||
# GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin.
|
||||
# Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
|
||||
|
||||
See the library [@http://www.boost.org/development/tests/release/developer/utility-identity_type.html regressions test results] for detailed information on supported compilers and platforms.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Annex: Usage]
|
||||
|
||||
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 when implementing a user-defined macro (as shown below).
|
||||
When [macroref BOOST_IDENTITY_TYPE] is used in the implementation of the user-defined macro, the caller of the user macro will have to specify the extra parenthesis (see also [@../../test/paren.cpp =paren.cpp=]):
|
||||
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 in the user macro definition, the call of the user macro will only have to specify the extra parenthesis (see also [@../../test/paren.cpp =paren.cpp=]):
|
||||
|
||||
[paren]
|
||||
|
||||
However, note that the caller will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma:
|
||||
However, note that the user will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma:
|
||||
|
||||
[paren_always]
|
||||
|
||||
In some cases, using [macroref BOOST_IDENTITY_TYPE] in the implementation of the user-defined macro might provide the best syntax for the caller.
|
||||
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]:
|
||||
|
||||
BOOST_MPL_ASSERT(( // Natural syntax.
|
||||
@@ -138,7 +147,7 @@ For example, this is the case for [@http://www.boost.org/libs/local_function `BO
|
||||
return x + y;
|
||||
} BOOST_LOCAL_FUNCTION_NAME(add)
|
||||
|
||||
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 (while still allowing to specify parameter types with commas as special cases using `BOOST_LOCAL_FUNCTION(BOOST_IDENTITY_TYPE((std::map<int, char>))& x, int& y)`).
|
||||
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]
|
||||
|
||||
@@ -147,7 +156,7 @@ Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when n
|
||||
The implementation of this library macro is equivalent to the following:
|
||||
[footnote
|
||||
There is absolutely no guarantee that the macro is actually implemented using the code listed in this documentation.
|
||||
The listed code is for explanatory purposes only.
|
||||
This code is for explanatory purposes only.
|
||||
]
|
||||
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
|
@@ -101,7 +101,12 @@ namespace boost
|
||||
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
||||
<< function << ":\n"
|
||||
<< file << '(' << line << "): " << msg << std::endl;
|
||||
#ifdef UNDER_CE
|
||||
// The Windows CE CRT library does not have abort() so use exit(-1) instead.
|
||||
std::exit(-1);
|
||||
#else
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
} // detail
|
||||
} // assertion
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
@@ -43,20 +44,26 @@ struct ct_imp2<T, true>
|
||||
typedef const T param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b1>
|
||||
template <typename T, bool isp, bool b1, bool b2>
|
||||
struct ct_imp
|
||||
{
|
||||
typedef const T& param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp>
|
||||
struct ct_imp<T, isp, true>
|
||||
template <typename T, bool isp, bool b2>
|
||||
struct ct_imp<T, isp, true, b2>
|
||||
{
|
||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b1>
|
||||
struct ct_imp<T, true, b1>
|
||||
template <typename T, bool isp, bool b1>
|
||||
struct ct_imp<T, isp, b1, true>
|
||||
{
|
||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b1, bool b2>
|
||||
struct ct_imp<T, true, b1, b2>
|
||||
{
|
||||
typedef const T param_type;
|
||||
};
|
||||
@@ -79,7 +86,8 @@ public:
|
||||
typedef typename boost::detail::ct_imp<
|
||||
T,
|
||||
::boost::is_pointer<T>::value,
|
||||
::boost::is_arithmetic<T>::value
|
||||
::boost::is_arithmetic<T>::value,
|
||||
::boost::is_enum<T>::value
|
||||
>::param_type param_type;
|
||||
};
|
||||
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/utility/binary.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/identity_type.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// boost utility/base_from_member.hpp header file --------------------------//
|
||||
|
||||
// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
|
||||
// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and
|
||||
// distribution are subject to the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or a copy at
|
||||
// <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
@@ -10,10 +10,15 @@
|
||||
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.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 ------------------------------//
|
||||
@@ -53,6 +58,59 @@
|
||||
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 -----------------------------------------//
|
||||
|
||||
// Helper to initialize a base object so a derived class can use this
|
||||
@@ -68,12 +126,24 @@ class base_from_member
|
||||
protected:
|
||||
MemberType member;
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && \
|
||||
!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 )
|
||||
BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType(
|
||||
static_cast<T&&>(x)... )) ) // no std::is_nothrow_constructible...
|
||||
: member( static_cast<T&&>(x)... ) // ...nor std::forward needed
|
||||
{}
|
||||
#else
|
||||
base_from_member()
|
||||
: member()
|
||||
{}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||
BOOST_PRIVATE_CTR_DEF, _ )
|
||||
#endif
|
||||
|
||||
}; // boost::base_from_member
|
||||
|
||||
|
@@ -13,7 +13,6 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
//#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
@@ -37,13 +36,9 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
//#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
//#else
|
||||
// template <typename T>
|
||||
// typename add_lvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
//#endif
|
||||
typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
|
@@ -28,15 +28,14 @@ This type expression can contain an arbitrary number of commas.
|
||||
}
|
||||
@EndParams
|
||||
|
||||
This macro works on any C++03 compiler (it does not use variadic macros).
|
||||
This macro works on any C++03 compiler (it does not require variadic macros).
|
||||
|
||||
This macro must be prefixed by <c>typename</c> when used within templates.
|
||||
Note that 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).
|
||||
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).
|
||||
|
||||
On some compilers (like GCC), using this macro on abstract types requires to
|
||||
add and remove a reference to the specified type.
|
||||
On some compilers (like GCC), using this macro on an abstract types requires to
|
||||
add and remove a reference to the type.
|
||||
*/
|
||||
#define BOOST_IDENTITY_TYPE(parenthesized_type) \
|
||||
/* must NOT prefix this with `::` to work with parenthesized syntax */ \
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include <boost/utility/declval.hpp>
|
||||
|
||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 16
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
10
index.html
10
index.html
@@ -14,21 +14,28 @@
|
||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||
<blockquote>
|
||||
<p>
|
||||
<a href="utility.htm#addressof">addressof</a><br>
|
||||
<a href="assert.html">assert</a><br>
|
||||
<a href="base_from_member.html">base_from_member</a><br>
|
||||
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
|
||||
<a href="call_traits.htm">call_traits</a><br>
|
||||
<a href="checked_delete.html">checked_delete</a><br>
|
||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||
<a href="current_function.html">current_function</a><br>
|
||||
<a href="doc/html/declval.html">declval</a><br>
|
||||
<a href="enable_if.html">enable_if</a><br>
|
||||
<a href="in_place_factories.html">in_place_factory</a><br>
|
||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||
<a href="utility.htm#functions_next_prior">next/prior</a><br>
|
||||
<a href="utility.htm#Class_noncopyable">noncopyable</a><br>
|
||||
<a href="operators.htm">operators</a><br>
|
||||
<a href="utility.htm#result_of">result_of</a><br>
|
||||
<a href="swap.html">swap</a><br>
|
||||
<a href="throw_exception.html">throw_exception</a><br>
|
||||
<a href="utility.htm">utility</a><br>
|
||||
<a href="value_init.htm">value_init</a></p>
|
||||
<a href="value_init.htm">value_init</a>
|
||||
</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
@@ -41,4 +48,3 @@
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@@ -155,7 +155,7 @@ void f() {
|
||||
the type <code>F</code> to be a function pointer,
|
||||
function reference, member function pointer, or class
|
||||
type. By default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
16. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>. Class template <code>result_of</code>
|
||||
resides in the header <code><<a
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
// Sample POD type
|
||||
@@ -215,7 +215,7 @@ template<class T>
|
||||
void check_initialized_value ( T const& y )
|
||||
{
|
||||
T initializedValue = boost::initialized_value ;
|
||||
BOOST_CHECK ( y == initializedValue ) ;
|
||||
BOOST_TEST ( y == initializedValue ) ;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
@@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& )
|
||||
template<class T>
|
||||
bool test ( T const& y, T const& z )
|
||||
{
|
||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||
const int errors_before_test = boost::detail::test_errors();
|
||||
|
||||
check_initialized_value(y);
|
||||
|
||||
boost::value_initialized<T> x ;
|
||||
BOOST_CHECK ( y == x ) ;
|
||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||
BOOST_TEST ( y == x ) ;
|
||||
BOOST_TEST ( y == boost::get(x) ) ;
|
||||
|
||||
static_cast<T&>(x) = z ;
|
||||
boost::get(x) = z ;
|
||||
BOOST_CHECK ( x == z ) ;
|
||||
BOOST_TEST ( x == z ) ;
|
||||
|
||||
boost::value_initialized<T> const x_c ;
|
||||
BOOST_CHECK ( y == x_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
||||
BOOST_TEST ( y == x_c ) ;
|
||||
BOOST_TEST ( y == boost::get(x_c) ) ;
|
||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||
x_c_ref = z ;
|
||||
BOOST_CHECK ( x_c == z ) ;
|
||||
BOOST_TEST ( x_c == z ) ;
|
||||
|
||||
boost::value_initialized<T> const copy1 = x;
|
||||
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
||||
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
||||
|
||||
boost::value_initialized<T> copy2;
|
||||
copy2 = x;
|
||||
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
||||
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||
|
||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||
BOOST_CHECK ( y == *ptr ) ;
|
||||
BOOST_TEST ( y == *ptr ) ;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
boost::value_initialized<T const> cx ;
|
||||
BOOST_CHECK ( y == cx ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
||||
BOOST_TEST ( y == cx ) ;
|
||||
BOOST_TEST ( y == boost::get(cx) ) ;
|
||||
|
||||
boost::value_initialized<T const> const cx_c ;
|
||||
BOOST_CHECK ( y == cx_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
||||
BOOST_TEST ( y == cx_c ) ;
|
||||
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
||||
#endif
|
||||
|
||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||
return boost::detail::test_errors() == errors_before_test ;
|
||||
}
|
||||
|
||||
int test_main(int, char **)
|
||||
int main(int, char **)
|
||||
{
|
||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
|
||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
|
||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
|
||||
StringAndInt stringAndInt0;
|
||||
StringAndInt stringAndInt1;
|
||||
stringAndInt0.i = 0;
|
||||
stringAndInt1.i = 1;
|
||||
stringAndInt1.s = std::string("1");
|
||||
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
||||
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
||||
|
||||
StructWithDestructor structWithDestructor0;
|
||||
StructWithDestructor structWithDestructor1;
|
||||
structWithDestructor0.i = 0;
|
||||
structWithDestructor1.i = 1;
|
||||
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
||||
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
||||
|
||||
StructWithVirtualFunction structWithVirtualFunction0;
|
||||
StructWithVirtualFunction structWithVirtualFunction1;
|
||||
structWithVirtualFunction0.i = 0;
|
||||
structWithVirtualFunction1.i = 1;
|
||||
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
|
||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||
get(swapFunctionCallTester1).data = 1;
|
||||
get(swapFunctionCallTester2).data = 2;
|
||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user