mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 22:10:54 +02:00
Compare commits
91 Commits
svn-branch
...
boost-1.50
Author | SHA1 | Date | |
---|---|---|---|
|
4fb06f9851 | ||
|
fb2d391928 | ||
|
ad5cf8cf08 | ||
|
2fc827ad23 | ||
|
88e7d86270 | ||
|
6b9f0103d5 | ||
|
7aa68731b4 | ||
|
87b3643647 | ||
|
c9d56eed6e | ||
|
e36315c151 | ||
|
1aa48ea698 | ||
|
d01eb82fb7 | ||
|
86791caf0e | ||
|
8176af84e1 | ||
|
b7d4b6edae | ||
|
d7cf3628f7 | ||
|
b273cd3914 | ||
|
ca7db1f361 | ||
|
2a7e81e07f | ||
|
13da21e7b1 | ||
|
b3ffef536d | ||
|
e2c98762db | ||
|
8af4250c3c | ||
|
e30889304c | ||
|
b4dee80e61 | ||
|
a47dce770c | ||
|
dab1e8e522 | ||
|
583422cda2 | ||
|
ee146a02a1 | ||
|
c131cbd0b2 | ||
|
f8bef7ba95 | ||
|
e54cbf3053 | ||
|
d5291d08b8 | ||
|
61755605af | ||
|
cd12e322bd | ||
|
8cb975feb7 | ||
|
ffe151458e | ||
|
4003a9f74a | ||
|
211eb04f33 | ||
|
e57213b298 | ||
|
51f9adbfa1 | ||
|
eaaf17a88f | ||
|
48cfd42123 | ||
|
76aa5d2f27 | ||
|
ce67dde4f0 | ||
|
a69e872a91 | ||
|
e3640e45c2 | ||
|
b7cd171b2b | ||
|
b2e6a82adb | ||
|
390372294a | ||
|
ffbbf38e12 | ||
|
9e73b2c6ae | ||
|
633832e872 | ||
|
862cb2a4e0 | ||
|
b012f16ee5 | ||
|
3d96ab26d4 | ||
|
8652bf51ec | ||
|
9168cb9c61 | ||
|
e1991374ae | ||
|
d0ee9a7c28 | ||
|
10e83b490b | ||
|
4b24dba257 | ||
|
7a036f6f3a | ||
|
e632b0fb1f | ||
|
17bee9d43f | ||
|
492a8ad213 | ||
|
8827b8ed8b | ||
|
8849fbc52d | ||
|
50bc75a802 | ||
|
9b52e49fda | ||
|
ab479794f3 | ||
|
97b8966337 | ||
|
88099a882f | ||
|
d5554eb6d7 | ||
|
13bdfb8bbd | ||
|
74462349c2 | ||
|
6aa648d315 | ||
|
9ff18c2c96 | ||
|
d5ea07c737 | ||
|
aa0096bf42 | ||
|
005c2f3cc8 | ||
|
09f7aab52d | ||
|
30a40f9f76 | ||
|
d9f8bae673 | ||
|
3c7b409460 | ||
|
ee3551e8dc | ||
|
95da2e90de | ||
|
6dd93ab916 | ||
|
505d419a1b | ||
|
d968b5f5b9 | ||
|
d809d4e832 |
@@ -129,8 +129,6 @@ particular member type does not need to concern itself with the integer.</p>
|
|||||||
<h2><a name="synopsis">Synopsis</a></h2>
|
<h2><a name="synopsis">Synopsis</a></h2>
|
||||||
|
|
||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
#include <type_traits> <i>// exposition only</i>
|
|
||||||
|
|
||||||
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
||||||
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
||||||
#endif
|
#endif
|
||||||
@@ -141,11 +139,6 @@ class boost::base_from_member
|
|||||||
protected:
|
protected:
|
||||||
MemberType member;
|
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();
|
base_from_member();
|
||||||
|
|
||||||
template< typename T1 >
|
template< typename T1 >
|
||||||
@@ -161,7 +154,6 @@ protected:
|
|||||||
typename T10 >
|
typename T10 >
|
||||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
|
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
|
||||||
T8 x8, T9 x9, T10 x10 );
|
T8 x8, T9 x9, T10 x10 );
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
@@ -174,27 +166,13 @@ 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>There is a default constructor and several constructor member
|
||||||
are present, there will be a single constructor template. It implements
|
templates. These constructor templates can take as many arguments
|
||||||
"perfect forwarding" to the best constructor call of
|
(currently up to ten) as possible and pass them to a constructor of
|
||||||
<code>member</code> (if any). The constructor template is marked both
|
the data member. Since C++ does not allow any way to explicitly state
|
||||||
<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.</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 template parameters of a templated constructor, make sure that
|
||||||
the arguments are already close as possible to the actual type used in
|
the arguments are already close as possible to the actual type used in
|
||||||
the data member's desired constructor. Explicit conversions may be
|
the data member's desired constructor.</p>
|
||||||
necessary.</p>
|
|
||||||
|
|
||||||
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies
|
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies
|
||||||
the maximum argument length for the constructor templates. The constant
|
the maximum argument length for the constructor templates. The constant
|
||||||
@@ -202,7 +180,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
|
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
|
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
|
uses this class template as a base class for a member with a flexible set of
|
||||||
constructors.) This constant is ignored when C++2011 features are present.</p>
|
constructors.)</p>
|
||||||
|
|
||||||
<h2><a name="usage">Usage</a></h2>
|
<h2><a name="usage">Usage</a></h2>
|
||||||
|
|
||||||
@@ -345,14 +323,11 @@ constructor argument for <code>pbase0_type</code> is converted from
|
|||||||
argument for <code>pbase2_type</code> is converted from <code>int</code>
|
argument for <code>pbase2_type</code> is converted from <code>int</code>
|
||||||
to <code>double</code>. The second constructor argument for
|
to <code>double</code>. The second constructor argument for
|
||||||
<code>pbase3_type</code> is a special case of necessary conversion; all
|
<code>pbase3_type</code> is a special case of necessary conversion; all
|
||||||
forms of the null-pointer literal in C++ (except <code>nullptr</code> from
|
forms of the null-pointer literal in C++ also look like compile-time
|
||||||
C++2011) also look like compile-time integral expressions, so C++ always
|
integral expressions, so C++ always interprets such code as an integer
|
||||||
interprets such code as an integer when it has overloads that can take either
|
when it has overloads that can take either an integer or a pointer. The
|
||||||
an integer or a pointer. The last conversion is necessary for the compiler to
|
last conversion is necessary for the compiler to call a constructor form
|
||||||
call a constructor form with the exact pointer type used in
|
with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||||
<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>
|
<h2><a name="credits">Credits</a></h2>
|
||||||
|
|
||||||
@@ -385,9 +360,9 @@ a constructor call but <code>std::nullptr_t</code> cannot.)</p>
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised: 11 February 2012</p>
|
<p>Revised: 28 August 2004</p>
|
||||||
|
|
||||||
<p>Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and distribution
|
<p>Copyright 2001, 2003, 2004 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
|
||||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a
|
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>
|
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||||
|
@@ -210,10 +210,8 @@ int main()
|
|||||||
comparible_UDT u;
|
comparible_UDT u;
|
||||||
c1(u);
|
c1(u);
|
||||||
call_traits_checker<int> c2;
|
call_traits_checker<int> c2;
|
||||||
call_traits_checker<enum_UDT> c2b;
|
|
||||||
int i = 2;
|
int i = 2;
|
||||||
c2(i);
|
c2(i);
|
||||||
c2b(one);
|
|
||||||
int* pi = &i;
|
int* pi = &i;
|
||||||
int a[2] = {1,2};
|
int a[2] = {1,2};
|
||||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
|
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
|
||||||
@@ -294,11 +292,7 @@ int main()
|
|||||||
BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
|
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>::const_reference);
|
||||||
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
[/
|
[/
|
||||||
/ Copyright (c) 2008 Howard Hinnant
|
/ Copyright (c) 2008 Howard Hinnant
|
||||||
/ Copyright (c) 2008 Beman Dawes
|
/ Copyright (c) 2009-20012 Vicente J. Botet Escriba
|
||||||
/ Copyright (c) 2009-20010 Vicente J. Botet Escriba
|
|
||||||
/
|
/
|
||||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
/ 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)
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -10,11 +9,9 @@
|
|||||||
[article Declval
|
[article Declval
|
||||||
[quickbook 1.5]
|
[quickbook 1.5]
|
||||||
[authors [Hinnant, Howard]]
|
[authors [Hinnant, Howard]]
|
||||||
[authors [Dawes, Beman]]
|
|
||||||
[authors [Botet Escriba, Vicente J.]]
|
[authors [Botet Escriba, Vicente J.]]
|
||||||
[copyright 2008 Howard Hinnant]
|
[copyright 2008 Howard Hinnant]
|
||||||
[copyright 2008 Beman Dawes]
|
[copyright 2009-2012 Vicente J. Botet Escriba]
|
||||||
[copyright 2009-2010 Vicente J. Botet Escriba]
|
|
||||||
[license
|
[license
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
(See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -77,7 +74,7 @@ This extremely light-weight function is expected to be part of the daily tool-bo
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template <typename T>
|
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
|
} // namespace boost
|
||||||
|
|
||||||
@@ -100,5 +97,19 @@ Declares a function template convert which only participates in overloading if t
|
|||||||
|
|
||||||
[endsect]
|
[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">
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||||
<title>Declval</title>
|
<title>Declval</title>
|
||||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||||
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
|
<meta name="generator" content="DocBook XSL Stylesheets V1.76.0">
|
||||||
<link rel="home" href="declval.html" title="Declval">
|
<link rel="home" href="declval.html" title="Declval">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||||
@@ -27,17 +27,13 @@
|
|||||||
<span class="firstname">Howard</span> <span class="surname">Hinnant</span>
|
<span class="firstname">Howard</span> <span class="surname">Hinnant</span>
|
||||||
</h3></div>
|
</h3></div>
|
||||||
<div class="author"><h3 class="author">
|
<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>
|
<span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span>
|
||||||
</h3></div>
|
</h3></div>
|
||||||
</div></div>
|
</div></div>
|
||||||
<div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div>
|
<div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div>
|
||||||
<div><p class="copyright">Copyright © 2008 Beman Dawes</p></div>
|
<div><p class="copyright">Copyright © 2009 -2012 Vicente J. Botet Escriba</p></div>
|
||||||
<div><p class="copyright">Copyright © 2009, 2010 Vicente J. Botet Escriba</p></div>
|
|
||||||
<div><div class="legalnotice">
|
<div><div class="legalnotice">
|
||||||
<a name="id3354293"></a><p>
|
<a name="idp13449552"></a><p>
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
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>)
|
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>
|
</p>
|
||||||
@@ -50,6 +46,7 @@
|
|||||||
<dl>
|
<dl>
|
||||||
<dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt>
|
<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.reference">Reference </a></span></dt>
|
||||||
|
<dt><span class="section"><a href="declval.html#declval.history">History</a></span></dt>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
@@ -122,7 +119,7 @@
|
|||||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
|
<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">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="comment">//noexcept; // 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="identifier">noexcept</span><span class="special">;</span> <span class="comment">// as unevaluated operand
|
||||||
</span>
|
</span>
|
||||||
<span class="special">}</span> <span class="comment">// namespace boost
|
<span class="special">}</span> <span class="comment">// namespace boost
|
||||||
</span></pre>
|
</span></pre>
|
||||||
@@ -152,9 +149,25 @@
|
|||||||
if the type From can be explicitly converted to type To.
|
if the type From can be explicitly converted to type To.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||||
<td align="left"><p><small>Last revised: April 06, 2011 at 20:06:10 GMT</small></p></td>
|
<td align="left"><p><small>Last revised: May 28, 2012 at 18:59:06 GMT</small></p></td>
|
||||||
<td align="right"><div class="copyright-footer"></div></td>
|
<td align="right"><div class="copyright-footer"></div></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
|
@@ -15,7 +15,7 @@ doxygen reference : ../../../../boost/utility/identity_type.hpp
|
|||||||
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
|
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
|
||||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||||
<doxygen:param>HIDE_UNDOC_CLASSES=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{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\" "
|
<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\" "
|
||||||
;
|
;
|
||||||
|
|
||||||
# This target must be called "index" so to generate "index.html" file.
|
# This target must be called "index" so to generate "index.html" file.
|
||||||
@@ -29,3 +29,16 @@ boostbook doc : index
|
|||||||
<xsl:param>boost.root=../../../../..
|
<xsl:param>boost.root=../../../../..
|
||||||
;
|
;
|
||||||
|
|
||||||
|
#
|
||||||
|
# This is very imperfect - it results in both html and pdf docs being built,
|
||||||
|
# for some reason I can't get the "onehtml" format specified above to play nice
|
||||||
|
# with the usual incantations for mixed pdf/html builds. JM 06/2012.
|
||||||
|
#
|
||||||
|
boostbook pdf_doc : index
|
||||||
|
:
|
||||||
|
<format>pdf
|
||||||
|
<format>html:<build>no
|
||||||
|
;
|
||||||
|
|
||||||
|
install pdf_doc_install : pdf_doc : <location>. <name>identity_type.pdf <install-type>PDF ;
|
||||||
|
explicit pdf_doc_install ;
|
||||||
|
@@ -4,16 +4,17 @@
|
|||||||
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>)
|
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.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>
|
Implementation</a></span></dt><dt><span class="section"><a href="#reference">Reference</a></span></dt></dl></div><p>
|
||||||
This library allows to wrap type expressions within round parenthesis so they
|
This library allows to wrap types within round parenthesis so they can always
|
||||||
can be passed to macros even when they contain commas.
|
be passed as macro parameters.
|
||||||
</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>,</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>,</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>.
|
||||||
@@ -35,50 +36,59 @@
|
|||||||
<code class="computeroutput"><span class="number">2</span></code>
|
<code class="computeroutput"><span class="number">2</span></code>
|
||||||
</li></ol></div><p>
|
</li></ol></div><p>
|
||||||
Note that, differently from the compiler, the preprocessor only recognizes
|
Note that, differently from the compiler, the preprocessor only recognizes
|
||||||
round parameters <code class="computeroutput"><span class="special">()</span></code>. Angular
|
round parenthesis <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
|
<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 the macro parameters.
|
when parsing 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>
|
</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
|
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 some cases
|
pass the type expression to the macro all together. For example, in the case
|
||||||
a <code class="computeroutput"><span class="keyword">typedef</span></code> can be used to specify
|
above a <code class="computeroutput"><span class="keyword">typedef</span></code> could have been
|
||||||
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>):
|
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><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>
|
</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>
|
<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 neither possible nor desired (e.g., see the function template
|
||||||
<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>
|
<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>
|
||||||
defines a macro <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</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
|
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>).
|
as one of the macro parameters (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="preprocessor">#include</span> <span class="special"><</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">></span>
|
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></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"><</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>
|
<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>
|
</pre><p>
|
||||||
</p><p>
|
</p><p>
|
||||||
This macro expands to an expression that evaluates (at compile-time) to the
|
The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro
|
||||||
specified type. The specified type is never split into multiple macro parameters
|
expands to an expression that evaluates (at compile-time) to the specified
|
||||||
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
|
type. The specified type is never split into multiple macro parameters because
|
||||||
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
|
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>.
|
type passed to the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((...))</span></code>.
|
||||||
</p><p>
|
</p><p>
|
||||||
This macro works on any <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
|
This macro works on any <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
|
||||||
compiler (because it does not use <a href="http://en.wikipedia.org/wiki/Variadic_macro" target="_top">variadic
|
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>
|
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.
|
||||||
</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"><</span><span class="keyword">typename</span> <span class="identifier">T</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">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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>)),</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>)),</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"><<</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</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"><<</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</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 +97,21 @@
|
|||||||
</p><pre class="programlisting"><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">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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">></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"><</span><span class="keyword">char</span><span class="special">>(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK.</span>
|
<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> <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"><</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 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,
|
||||||
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 <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code> would
|
||||||
limitation does not apply to class templates because class template parameters
|
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
|
||||||
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
|
template parameters must always be explicitly specified.) In other words, without
|
||||||
normally be able to implicitly deduce the function template parameter as shown
|
using the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
|
||||||
below:
|
macro, C++ would normally be able to automatically deduce the function template
|
||||||
|
parameter as shown below:
|
||||||
</p><p>
|
</p><p>
|
||||||
</p><pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
</p><pre class="programlisting"><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">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,21 +121,20 @@
|
|||||||
<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"><</span><span class="keyword">char</span><span class="special">>(</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"><</span><span class="keyword">char</span><span class="special">>(</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 avoided by manipulating the type adding and removing a reference to it.
|
||||||
to 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
|
||||||
to pass a meta-function with multiple template parameters to the assert macro
|
to pass a meta-function with multiple template parameters to the assert macro
|
||||||
(so to handle the commas separating the template parameters). In this case,
|
(so to handle the commas separating the template parameters). In this case,
|
||||||
if the meta-function is an abstract type, it needs to be manipulated adding
|
if the meta-function is an abstract type, it needs to be manipulated adding
|
||||||
and removing a reference to it (see also <a href="../../test/tmp_assert.cpp" target="_top"><code class="literal">tmp_assert.cpp</code></a>):
|
and removing a reference to it (see also <a href="../../test/abstract.cpp" target="_top"><code class="literal">abstract.cpp</code></a>):
|
||||||
</p><p>
|
</p><p>
|
||||||
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">)</span> <span class="special">\</span>
|
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">)</span> <span class="special">\</span>
|
||||||
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">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">metafunction</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span>
|
||||||
@@ -132,7 +142,7 @@
|
|||||||
<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">bool</span> <span class="identifier">b</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">bool</span> <span class="identifier">b</span><span class="special">></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">&</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">&</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 +157,37 @@
|
|||||||
</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 when implementing a user-defined macro (as shown below).
|
||||||
the call of the user macro will only have to specify the extra parenthesis
|
When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> is
|
||||||
(see also <a href="../../test/tmp_assert.cpp" target="_top"><code class="literal">tmp_assert.cpp</code></a>):
|
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>):
|
||||||
</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"><</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> <span class="special">));</span>
|
<span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">)</span> <span class="special">\</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"><</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> <span class="special">);</span>
|
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span>
|
||||||
|
|
||||||
|
<span class="comment">// Specify only extra parenthesis `((...))`.</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"><</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>
|
||||||
|
|
||||||
|
<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"><</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>
|
</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 caller 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"><</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">></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"><</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">>));</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"><</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">></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"><</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">>);</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
|
in the implementation of the user-defined macro might provide the best syntax
|
||||||
the case for <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code>
|
for the caller. 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 +199,23 @@
|
|||||||
<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">&))</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&))</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">&))</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&))</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">&</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">&</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
|
<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.
|
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>).
|
||||||
</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"><</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">></span>
|
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></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,25 +223,30 @@
|
|||||||
</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"><</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"><</span><span class="keyword">int</span><span class="special">,</span>
|
||||||
<span class="keyword">char</span><span class="special">>)</span></code>
|
<span class="keyword">char</span><span class="special">>)</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>)</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">>)</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 <boost/utility/identity_type.hpp>"><div class="titlepage"><div><div><h3 class="title"><a name="header.boost.utility.identity_type_hpp"></a>Header <<a href="../../../../../boost/utility/identity_type.hpp" target="_top">boost/utility/identity_type.hpp</a>></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 <boost/utility/identity_type.hpp>"><div class="titlepage"><div><div><h3 class="title"><a name="header.boost.utility.identity_type_hpp"></a>Header <<a href="../../../../../boost/utility/identity_type.hpp" target="_top">boost/utility/identity_type.hpp</a>></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: <<a class="link" href="#header.boost.utility.identity_type_hpp" title="Header <boost/utility/identity_type.hpp>">boost/utility/identity_type.hpp</a>>
|
<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="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="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 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 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>
|
||||||
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. The listed code is for explanatory
|
||||||
only.
|
purposes only.
|
||||||
</p></div></div></div></body></html>
|
</p></div></div></div></body></html>
|
||||||
|
@@ -19,18 +19,19 @@
|
|||||||
[category Utilities]
|
[category Utilities]
|
||||||
]
|
]
|
||||||
|
|
||||||
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 types within round parenthesis so they can always be passed as macro parameters.
|
||||||
|
|
||||||
[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/abstract.cpp]
|
||||||
|
[import ../test/paren.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:
|
||||||
@@ -46,45 +47,50 @@ The preprocessor interprets that unwrapped comma as a separation between macro p
|
|||||||
# `char>`
|
# `char>`
|
||||||
# `2`
|
# `2`
|
||||||
|
|
||||||
Note that, differently from the compiler, the preprocessor only recognizes round parameters `()`.
|
Note that, differently from the compiler, the preprocessor only recognizes round parenthesis `()`.
|
||||||
Angular `<>` or squared `[]` parenthesis are not used by the preprocessor when parsing the macro parameters.
|
Angular `<>` and squared `[]` parenthesis are not recognized by the preprocessor when parsing macro parameters.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section Solution]
|
[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.
|
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 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=]):
|
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=]):
|
||||||
|
|
||||||
[var_typedef]
|
[var_typedef]
|
||||||
|
|
||||||
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=]).
|
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=]).
|
||||||
|
|
||||||
[var_ok]
|
[var_ok]
|
||||||
|
|
||||||
This macro expands to an expression that evaluates (at compile-time) to the specified type.
|
The [macroref BOOST_IDENTITY_TYPE] 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 `()`.
|
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((...))`.
|
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 (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 (and 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).
|
||||||
]
|
]
|
||||||
|
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]
|
[endsect]
|
||||||
|
|
||||||
[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 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 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 `f(a)` would have done.
|
||||||
|
[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,29 +99,29 @@ 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 avoided 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`]).
|
||||||
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).
|
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).
|
||||||
In this case, if the meta-function is an abstract type, it needs to be manipulated adding and removing a reference to it (see also [@../../test/tmp_assert.cpp =tmp_assert.cpp=]):
|
In this case, if the meta-function is an abstract type, it needs to be manipulated adding and removing a reference to it (see also [@../../test/abstract.cpp =abstract.cpp=]):
|
||||||
|
|
||||||
[tmp_assert_abstract]
|
[abstract]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[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 when implementing 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 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=]):
|
||||||
|
|
||||||
[tmp_assert_alternative]
|
[paren]
|
||||||
|
|
||||||
However, note that the user will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma:
|
However, note that the caller will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma:
|
||||||
|
|
||||||
[tmp_assert_alternative_always]
|
[paren_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] in the implementation of the user-defined macro might provide the best syntax for the caller.
|
||||||
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 +131,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 (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)`).
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -141,7 +147,7 @@ Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] when needed
|
|||||||
The implementation of this library macro is equivalent to the following:
|
The implementation of this library macro is equivalent to the following:
|
||||||
[footnote
|
[footnote
|
||||||
There is absolutely no guarantee that the macro is actually implemented using the code listed in this documentation.
|
There is absolutely no guarantee that the macro is actually implemented using the code listed in this documentation.
|
||||||
This code is for explanatory purposes only.
|
The listed code is for explanatory purposes only.
|
||||||
]
|
]
|
||||||
|
|
||||||
#include <boost/type_traits/function_traits.hpp>
|
#include <boost/type_traits/function_traits.hpp>
|
||||||
@@ -149,9 +155,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]
|
||||||
|
|
||||||
|
@@ -7,8 +7,10 @@
|
|||||||
|
|
||||||
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 abstract.cpp ;
|
||||||
|
run noncopyable.cpp ;
|
||||||
|
run paren.cpp ;
|
||||||
|
|
||||||
|
@@ -7,19 +7,17 @@
|
|||||||
|
|
||||||
#include <boost/utility/identity_type.hpp>
|
#include <boost/utility/identity_type.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/type_traits/is_const.hpp>
|
|
||||||
#include <boost/type_traits/add_reference.hpp>
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
//[tmp_assert_abstract
|
//[abstract
|
||||||
#define TMP_ASSERT(metafunction) \
|
#define TMP_ASSERT(metafunction) \
|
||||||
BOOST_STATIC_ASSERT(metafunction::value)
|
BOOST_STATIC_ASSERT(metafunction::value)
|
||||||
|
|
||||||
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(
|
||||||
@@ -33,19 +31,5 @@ TMP_ASSERT(
|
|||||||
);
|
);
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[tmp_assert_alternative
|
|
||||||
#define TMP_ASSERT_PAREN(parenthesized_metafunction) \
|
|
||||||
/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
|
|
||||||
BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
|
|
||||||
|
|
||||||
TMP_ASSERT_PAREN(( boost::is_const<std::map<int, char> const> ));
|
|
||||||
TMP_ASSERT( BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)) );
|
|
||||||
//]
|
|
||||||
|
|
||||||
//[tmp_assert_alternative_always
|
|
||||||
TMP_ASSERT_PAREN(( boost::is_const<int const> )); // Always extra `()`.
|
|
||||||
TMP_ASSERT( boost::is_const<int const> ); // No extra `()` and no macro.
|
|
||||||
//]
|
|
||||||
|
|
||||||
int main() { return 0; }
|
int main() { return 0; }
|
||||||
|
|
25
identity_type/test/noncopyable.cpp
Normal file
25
identity_type/test/noncopyable.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
// Copyright (C) 2009-2012 Lorenzo Caminiti
|
||||||
|
// Distributed under 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)
|
||||||
|
// Home at http://www.boost.org/libs/utility/identity_type
|
||||||
|
|
||||||
|
#include <boost/utility/identity_type.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
//[noncopyable
|
||||||
|
#define TMP_ASSERT(metafunction) \
|
||||||
|
BOOST_STATIC_ASSERT(metafunction::value)
|
||||||
|
|
||||||
|
template<typename T, T init>
|
||||||
|
struct noncopyable : boost::noncopyable {
|
||||||
|
static const T value = init;
|
||||||
|
};
|
||||||
|
|
||||||
|
TMP_ASSERT(BOOST_IDENTITY_TYPE((noncopyable<bool, true>)));
|
||||||
|
//]
|
||||||
|
|
||||||
|
int main() { return 0; }
|
||||||
|
|
35
identity_type/test/paren.cpp
Normal file
35
identity_type/test/paren.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// Copyright (C) 2009-2012 Lorenzo Caminiti
|
||||||
|
// Distributed under 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)
|
||||||
|
// Home at http://www.boost.org/libs/utility/identity_type
|
||||||
|
|
||||||
|
#include <boost/utility/identity_type.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
//[paren
|
||||||
|
#define TMP_ASSERT_PAREN(parenthesized_metafunction) \
|
||||||
|
/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
|
||||||
|
BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
|
||||||
|
|
||||||
|
#define TMP_ASSERT(metafunction) \
|
||||||
|
BOOST_STATIC_ASSERT(metafunction::value)
|
||||||
|
|
||||||
|
// Specify only extra parenthesis `((...))`.
|
||||||
|
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>)));
|
||||||
|
//]
|
||||||
|
|
||||||
|
//[paren_always
|
||||||
|
TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
|
||||||
|
|
||||||
|
TMP_ASSERT(boost::is_const<int const>); // No extra `((...))` and no macro.
|
||||||
|
//]
|
||||||
|
|
||||||
|
int main() { return 0; }
|
||||||
|
|
@@ -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;
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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; }
|
@@ -101,12 +101,7 @@ namespace boost
|
|||||||
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
||||||
<< function << ":\n"
|
<< function << ":\n"
|
||||||
<< file << '(' << line << "): " << msg << std::endl;
|
<< 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();
|
std::abort();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // detail
|
} // detail
|
||||||
} // assertion
|
} // assertion
|
||||||
|
@@ -24,7 +24,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include <boost/type_traits/is_arithmetic.hpp>
|
#include <boost/type_traits/is_arithmetic.hpp>
|
||||||
#include <boost/type_traits/is_enum.hpp>
|
|
||||||
#include <boost/type_traits/is_pointer.hpp>
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
@@ -44,26 +43,20 @@ struct ct_imp2<T, true>
|
|||||||
typedef const T param_type;
|
typedef const T param_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, bool isp, bool b1, bool b2>
|
template <typename T, bool isp, bool b1>
|
||||||
struct ct_imp
|
struct ct_imp
|
||||||
{
|
{
|
||||||
typedef const T& param_type;
|
typedef const T& param_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, bool isp, bool b2>
|
template <typename T, bool isp>
|
||||||
struct ct_imp<T, isp, true, b2>
|
struct ct_imp<T, isp, true>
|
||||||
{
|
{
|
||||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, bool isp, bool b1>
|
template <typename T, bool b1>
|
||||||
struct ct_imp<T, isp, b1, true>
|
struct ct_imp<T, true, b1>
|
||||||
{
|
|
||||||
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;
|
typedef const T param_type;
|
||||||
};
|
};
|
||||||
@@ -86,8 +79,7 @@ public:
|
|||||||
typedef typename boost::detail::ct_imp<
|
typedef typename boost::detail::ct_imp<
|
||||||
T,
|
T,
|
||||||
::boost::is_pointer<T>::value,
|
::boost::is_pointer<T>::value,
|
||||||
::boost::is_arithmetic<T>::value,
|
::boost::is_arithmetic<T>::value
|
||||||
::boost::is_enum<T>::value
|
|
||||||
>::param_type param_type;
|
>::param_type param_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <boost/utility/base_from_member.hpp>
|
#include <boost/utility/base_from_member.hpp>
|
||||||
#include <boost/utility/binary.hpp>
|
#include <boost/utility/binary.hpp>
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/utility/identity_type.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/next_prior.hpp>
|
#include <boost/next_prior.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// boost utility/base_from_member.hpp header file --------------------------//
|
// boost utility/base_from_member.hpp header file --------------------------//
|
||||||
|
|
||||||
// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and
|
// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
|
||||||
// distribution are subject to the Boost Software License, Version 1.0. (See
|
// distribution are subject to the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or a copy at
|
// accompanying file LICENSE_1_0.txt or a copy at
|
||||||
// <http://www.boost.org/LICENSE_1_0.txt>.)
|
// <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||||
#define 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/arithmetic/inc.hpp>
|
||||||
#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>
|
||||||
@@ -69,21 +68,12 @@ class base_from_member
|
|||||||
protected:
|
protected:
|
||||||
MemberType member;
|
MemberType member;
|
||||||
|
|
||||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
|
||||||
template <typename ...T>
|
|
||||||
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()
|
base_from_member()
|
||||||
: member()
|
: member()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||||
BOOST_PRIVATE_CTR_DEF, _ )
|
BOOST_PRIVATE_CTR_DEF, _ )
|
||||||
#endif
|
|
||||||
|
|
||||||
}; // boost::base_from_member
|
}; // boost::base_from_member
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||||
|
//#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
// //
|
// //
|
||||||
@@ -36,9 +37,13 @@
|
|||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
|
//#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
|
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
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||||
|
@@ -28,14 +28,15 @@ This type expression can contain an arbitrary number of commas.
|
|||||||
}
|
}
|
||||||
@EndParams
|
@EndParams
|
||||||
|
|
||||||
This macro works on any C++03 compiler (it does not require variadic macros).
|
This macro works on any C++03 compiler (it does not use variadic macros).
|
||||||
|
|
||||||
This macro must be prefixed by <c>typename</c> when used within templates.
|
This macro must be prefixed by <c>typename</c> 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
|
Note that the compiler will not be able to automatically determine function
|
||||||
be explicitly specified when calling the function template).
|
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 an abstract types requires to
|
On some compilers (like GCC), using this macro on abstract types requires to
|
||||||
add and remove a reference to the type.
|
add and remove a reference to the specified type.
|
||||||
*/
|
*/
|
||||||
#define BOOST_IDENTITY_TYPE(parenthesized_type) \
|
#define BOOST_IDENTITY_TYPE(parenthesized_type) \
|
||||||
/* must NOT prefix this with `::` to work with parenthesized syntax */ \
|
/* must NOT prefix this with `::` to work with parenthesized syntax */ \
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
#include <boost/utility/declval.hpp>
|
#include <boost/utility/declval.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||||
# define BOOST_RESULT_OF_NUM_ARGS 16
|
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
10
index.html
10
index.html
@@ -14,28 +14,21 @@
|
|||||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>
|
<p>
|
||||||
<a href="utility.htm#addressof">addressof</a><br>
|
|
||||||
<a href="assert.html">assert</a><br>
|
<a href="assert.html">assert</a><br>
|
||||||
<a href="base_from_member.html">base_from_member</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="call_traits.htm">call_traits</a><br>
|
||||||
<a href="checked_delete.html">checked_delete</a><br>
|
<a href="checked_delete.html">checked_delete</a><br>
|
||||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||||
<a href="current_function.html">current_function</a><br>
|
<a href="current_function.html">current_function</a><br>
|
||||||
<a href="doc/html/declval.html">declval</a><br>
|
<a href="doc/html/declval.html">declval</a><br>
|
||||||
<a href="enable_if.html">enable_if</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="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||||
<a href="generator_iterator.htm">generator 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="operators.htm">operators</a><br>
|
||||||
<a href="utility.htm#result_of">result_of</a><br>
|
|
||||||
<a href="swap.html">swap</a><br>
|
<a href="swap.html">swap</a><br>
|
||||||
<a href="throw_exception.html">throw_exception</a><br>
|
<a href="throw_exception.html">throw_exception</a><br>
|
||||||
<a href="utility.htm">utility</a><br>
|
<a href="utility.htm">utility</a><br>
|
||||||
<a href="value_init.htm">value_init</a>
|
<a href="value_init.htm">value_init</a></p>
|
||||||
</p>
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<hr>
|
<hr>
|
||||||
<p>© Copyright Beman Dawes, 2001</p>
|
<p>© Copyright Beman Dawes, 2001</p>
|
||||||
@@ -48,3 +41,4 @@
|
|||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
0
test/next_prior_test.cpp
Executable file → Normal file
0
test/next_prior_test.cpp
Executable file → Normal file
@@ -155,7 +155,7 @@ void f() {
|
|||||||
the type <code>F</code> to be a function pointer,
|
the type <code>F</code> to be a function pointer,
|
||||||
function reference, member function pointer, or class
|
function reference, member function pointer, or class
|
||||||
type. By default, <em>N</em> may be any value between 0 and
|
type. By default, <em>N</em> may be any value between 0 and
|
||||||
16. To change the upper limit, define the macro
|
10. To change the upper limit, define the macro
|
||||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||||
value for <em>N</em>. Class template <code>result_of</code>
|
value for <em>N</em>. Class template <code>result_of</code>
|
||||||
resides in the header <code><<a
|
resides in the header <code><<a
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include "boost/test/minimal.hpp"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sample POD type
|
// Sample POD type
|
||||||
@@ -215,7 +215,7 @@ template<class T>
|
|||||||
void check_initialized_value ( T const& y )
|
void check_initialized_value ( T const& y )
|
||||||
{
|
{
|
||||||
T initializedValue = boost::initialized_value ;
|
T initializedValue = boost::initialized_value ;
|
||||||
BOOST_TEST ( y == initializedValue ) ;
|
BOOST_CHECK ( y == initializedValue ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
@@ -245,125 +245,128 @@ void check_initialized_value( NonPOD const& )
|
|||||||
template<class T>
|
template<class T>
|
||||||
bool test ( T const& y, T const& z )
|
bool test ( T const& y, T const& z )
|
||||||
{
|
{
|
||||||
const int errors_before_test = boost::detail::test_errors();
|
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||||
|
|
||||||
check_initialized_value(y);
|
check_initialized_value(y);
|
||||||
|
|
||||||
boost::value_initialized<T> x ;
|
boost::value_initialized<T> x ;
|
||||||
BOOST_TEST ( y == x ) ;
|
BOOST_CHECK ( y == x ) ;
|
||||||
BOOST_TEST ( y == boost::get(x) ) ;
|
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||||
|
|
||||||
static_cast<T&>(x) = z ;
|
static_cast<T&>(x) = z ;
|
||||||
boost::get(x) = z ;
|
boost::get(x) = z ;
|
||||||
BOOST_TEST ( x == z ) ;
|
BOOST_CHECK ( x == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const x_c ;
|
boost::value_initialized<T> const x_c ;
|
||||||
BOOST_TEST ( y == x_c ) ;
|
BOOST_CHECK ( y == x_c ) ;
|
||||||
BOOST_TEST ( y == boost::get(x_c) ) ;
|
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
||||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||||
x_c_ref = z ;
|
x_c_ref = z ;
|
||||||
BOOST_TEST ( x_c == z ) ;
|
BOOST_CHECK ( x_c == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const copy1 = x;
|
boost::value_initialized<T> const copy1 = x;
|
||||||
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> copy2;
|
boost::value_initialized<T> copy2;
|
||||||
copy2 = x;
|
copy2 = x;
|
||||||
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||||
BOOST_TEST ( y == *ptr ) ;
|
BOOST_CHECK ( y == *ptr ) ;
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
boost::value_initialized<T const> cx ;
|
boost::value_initialized<T const> cx ;
|
||||||
BOOST_TEST ( y == cx ) ;
|
BOOST_CHECK ( y == cx ) ;
|
||||||
BOOST_TEST ( y == boost::get(cx) ) ;
|
BOOST_CHECK ( y == boost::get(cx) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T const> const cx_c ;
|
boost::value_initialized<T const> const cx_c ;
|
||||||
BOOST_TEST ( y == cx_c ) ;
|
BOOST_CHECK ( y == cx_c ) ;
|
||||||
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return boost::detail::test_errors() == errors_before_test ;
|
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, char **)
|
int test_main(int, char **)
|
||||||
{
|
{
|
||||||
BOOST_TEST ( test( 0,1234 ) ) ;
|
BOOST_CHECK ( test( 0,1234 ) ) ;
|
||||||
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
||||||
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||||
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||||
|
|
||||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||||
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||||
|
|
||||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||||
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||||
|
|
||||||
StringAndInt stringAndInt0;
|
StringAndInt stringAndInt0;
|
||||||
StringAndInt stringAndInt1;
|
StringAndInt stringAndInt1;
|
||||||
stringAndInt0.i = 0;
|
stringAndInt0.i = 0;
|
||||||
stringAndInt1.i = 1;
|
stringAndInt1.i = 1;
|
||||||
stringAndInt1.s = std::string("1");
|
stringAndInt1.s = std::string("1");
|
||||||
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
||||||
|
|
||||||
StructWithDestructor structWithDestructor0;
|
StructWithDestructor structWithDestructor0;
|
||||||
StructWithDestructor structWithDestructor1;
|
StructWithDestructor structWithDestructor1;
|
||||||
structWithDestructor0.i = 0;
|
structWithDestructor0.i = 0;
|
||||||
structWithDestructor1.i = 1;
|
structWithDestructor1.i = 1;
|
||||||
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
||||||
|
|
||||||
StructWithVirtualFunction structWithVirtualFunction0;
|
StructWithVirtualFunction structWithVirtualFunction0;
|
||||||
StructWithVirtualFunction structWithVirtualFunction1;
|
StructWithVirtualFunction structWithVirtualFunction1;
|
||||||
structWithVirtualFunction0.i = 0;
|
structWithVirtualFunction0.i = 0;
|
||||||
structWithVirtualFunction1.i = 1;
|
structWithVirtualFunction1.i = 1;
|
||||||
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||||
|
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||||
|
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||||
|
|
||||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||||
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||||
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||||
get(swapFunctionCallTester1).data = 1;
|
get(swapFunctionCallTester1).data = 1;
|
||||||
get(swapFunctionCallTester2).data = 2;
|
get(swapFunctionCallTester2).data = 2;
|
||||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||||
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
||||||
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
||||||
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||||
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||||
|
|
||||||
return boost::report_errors();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int expected_failures = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user