mirror of
https://github.com/boostorg/utility.git
synced 2025-10-05 21:40:59 +02:00
Compare commits
1 Commits
boost-1.49
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
4e1128e55c |
74
assert.html
74
assert.html
@@ -17,89 +17,36 @@
|
||||
<td colspan="2" height="64"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
<a href="#BOOST_ASSERT">BOOST_ASSERT</a><br>
|
||||
<a href="#BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a><br>
|
||||
<a href="#BOOST_VERIFY">BOOST_VERIFY</a></p>
|
||||
|
||||
<h2><a name="BOOST_ASSERT">BOOST_ASSERT</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT</b>,
|
||||
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>.
|
||||
The macro is intended to be used in both Boost libraries and user
|
||||
code.
|
||||
The macro is intended to be used in Boost libraries.
|
||||
</p>
|
||||
<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P>
|
||||
<P>If the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
<P>When the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
is included, <tt>BOOST_ASSERT(expr)</tt> is defined as <tt>((void)0)</tt>. This
|
||||
allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without
|
||||
affecting the definition of the standard <STRONG>assert</STRONG>.</P>
|
||||
<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
<P>When the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
is included, <tt>BOOST_ASSERT(expr)</tt> evaluates <b>expr</b> and, if the
|
||||
result is false, evaluates the expression</P>
|
||||
<blockquote>
|
||||
<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
||||
__FILE__, __LINE__)</tt></P>
|
||||
</blockquote>
|
||||
<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
||||
as</P>
|
||||
<blockquote>
|
||||
<pre>namespace boost
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line);
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line);
|
||||
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>but it is never defined. The user is expected to supply an appropriate
|
||||
definition.</p>
|
||||
<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG>
|
||||
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG>
|
||||
will be redefined each time as specified above.</P>
|
||||
|
||||
<h2><a name="BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT_MSG</b>,
|
||||
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>,
|
||||
but with an additional macro parameter supplying an error message. The macro is intended to be used in both Boost libraries
|
||||
and user code.
|
||||
</p>
|
||||
<P> <tt>BOOST_ASSERT_MSG(expr, msg)</tt> is equivalent to <code>
|
||||
((void)0)</code> if <b>BOOST_DISABLE_ASSERTS</b> or <b>NDEBUG</b> are
|
||||
defined or <code>expr</code> evaluates to <code>true</code>. If those
|
||||
macros and <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> are not
|
||||
defined, and <code>expr</code> evaluates to <code>false</code>, an error
|
||||
message that includes <tt>#expr</tt>, <tt>msg</tt>, <tt> <a href="current_function.html">BOOST_CURRENT_FUNCTION</a></tt>, <tt>
|
||||
__FILE__</tt>, and <tt>__LINE__</tt> is sent to output stream <b>
|
||||
BOOST_ASSERT_MSG_OSTREAM</b>
|
||||
and <code>std::abort()</code> is called.</P>
|
||||
<P> <b>BOOST_ASSERT_MSG_OSTREAM</b> defines the output stream. It defaults to <code>std::cerr</code>.
|
||||
Integrated development environments (IDE's) like Microsoft Visual Studio
|
||||
may produce easier to understand output if messages go to a different
|
||||
stream, such as <code>std::cout</code>. Users may define <b>BOOST_ASSERT_MSG_OSTREAM</b> before including <STRONG><boost/assert.hpp></STRONG>
|
||||
to specify a different output stream. </P>
|
||||
<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
is included, instead of sending a error message to an output
|
||||
stream, this expression is evaluated</P>
|
||||
<blockquote>
|
||||
<P><tt>::boost::assertion_failed_msg(#expr, msg, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
||||
__FILE__, __LINE__)</tt></P>
|
||||
</blockquote>
|
||||
<P><STRONG>assertion_failed_msg</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
||||
as</P>
|
||||
<blockquote>
|
||||
<pre>namespace boost
|
||||
{
|
||||
void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>but it is never defined. The user is expected to supply an appropriate
|
||||
definition.</p>
|
||||
<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG>
|
||||
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT_MSG</STRONG>
|
||||
will be redefined each time as specified above.</P>
|
||||
|
||||
<h2><a name="BOOST_VERIFY">BOOST_VERIFY</a></h2>
|
||||
<p><STRONG><boost/assert.hpp></STRONG> also defines the macro <STRONG>BOOST_VERIFY</STRONG>.
|
||||
It has exactly the same behavior as <STRONG>BOOST_ASSERT</STRONG>, except that
|
||||
the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always
|
||||
@@ -107,9 +54,8 @@
|
||||
effects; it can also help suppress warnings about unused variables when the
|
||||
only use of the variable is inside an assertion.</p>
|
||||
<p><br>
|
||||
<small>Copyright <20> 2002, 2007 by Peter Dimov. Copyright <20> 2011
|
||||
by Beman Dawes. Distributed under the Boost Software
|
||||
<small>Copyright <20> 2002, 2007 by Peter Dimov. Distributed under the Boost Software
|
||||
License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
|
||||
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -2,7 +2,6 @@
|
||||
// assert_test.cpp - a test for boost/assert.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (2) Beman Dawes 2011
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,11 +20,6 @@ void test_default()
|
||||
BOOST_ASSERT(x);
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg");
|
||||
BOOST_ASSERT_MSG(x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg");
|
||||
BOOST_ASSERT_MSG(&x, "msg");
|
||||
}
|
||||
|
||||
#define BOOST_DISABLE_ASSERTS
|
||||
@@ -40,23 +34,13 @@ void test_disabled()
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg");
|
||||
BOOST_ASSERT_MSG(x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg");
|
||||
BOOST_ASSERT_MSG(&x, "msg");
|
||||
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT(!x);
|
||||
BOOST_ASSERT(x == 0);
|
||||
|
||||
BOOST_ASSERT_MSG(0, "msg");
|
||||
BOOST_ASSERT_MSG(!x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 0, "msg");
|
||||
|
||||
void * p = 0;
|
||||
|
||||
BOOST_ASSERT(p);
|
||||
BOOST_ASSERT_MSG(p, "msg");
|
||||
|
||||
// supress warnings
|
||||
p = &x;
|
||||
@@ -71,7 +55,6 @@ void test_disabled()
|
||||
#include <cstdio>
|
||||
|
||||
int handler_invoked = 0;
|
||||
int msg_handler_invoked = 0;
|
||||
|
||||
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
||||
{
|
||||
@@ -83,24 +66,11 @@ void boost::assertion_failed(char const * expr, char const * function, char cons
|
||||
++handler_invoked;
|
||||
}
|
||||
|
||||
void boost::assertion_failed_msg(char const * expr, char const * msg, char const * function,
|
||||
char const * file, long line)
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::printf;
|
||||
#endif
|
||||
|
||||
printf("Expression: %s Message: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n",
|
||||
expr, msg, function, file, line);
|
||||
++msg_handler_invoked;
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
static void f()
|
||||
{
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT_MSG(0, "msg f()");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -113,35 +83,21 @@ void test_handler()
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg2");
|
||||
BOOST_ASSERT_MSG(x, "msg3");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg4");
|
||||
BOOST_ASSERT_MSG(&x, "msg5");
|
||||
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT(!x);
|
||||
BOOST_ASSERT(x == 0);
|
||||
|
||||
BOOST_ASSERT_MSG(0,"msg 0");
|
||||
BOOST_ASSERT_MSG(!x, "msg !x");
|
||||
BOOST_ASSERT_MSG(x == 0, "msg x == 0");
|
||||
|
||||
void * p = 0;
|
||||
|
||||
BOOST_ASSERT(p);
|
||||
BOOST_ASSERT_MSG(p, "msg p");
|
||||
|
||||
X::f();
|
||||
|
||||
BOOST_ASSERT(handler_invoked == 5);
|
||||
BOOST_TEST(handler_invoked == 5);
|
||||
|
||||
BOOST_ASSERT_MSG(msg_handler_invoked == 5, "msg_handler_invoked count is wrong");
|
||||
BOOST_TEST(msg_handler_invoked == 5);
|
||||
}
|
||||
|
||||
#undef BOOST_ENABLE_ASSERT_HANDLER
|
||||
#undef BOOST_ENABLE_ASSERT_MSG_HANDLER
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@@ -1,68 +0,0 @@
|
||||
|
||||
# Copyright John Maddock 2005. Use, modification, and distribution are
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
project : requirements
|
||||
# Path for links to Boost:
|
||||
<xsl:param>boost.root=../../../..
|
||||
|
||||
# Some general style settings:
|
||||
<xsl:param>table.footnote.number.format=1
|
||||
<xsl:param>footnote.number.format=1
|
||||
|
||||
# HTML options first:
|
||||
# Use graphics not text for navigation:
|
||||
<xsl:param>navig.graphics=1
|
||||
# PDF Options:
|
||||
# TOC Generation: this is needed for FOP-0.9 and later:
|
||||
<xsl:param>fop1.extensions=0
|
||||
<xsl:param>xep.extensions=1
|
||||
# TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
|
||||
<xsl:param>fop.extensions=0
|
||||
# No indent on body text:
|
||||
<xsl:param>body.start.indent=0pt
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.inner=0.5in
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.outer=0.5in
|
||||
# Paper type = A4
|
||||
<xsl:param>paper.type=A4
|
||||
# Yes, we want graphics for admonishments:
|
||||
<xsl:param>admon.graphics=1
|
||||
# Set this one for PDF generation *only*:
|
||||
# default pnd graphics are awful in PDF form,
|
||||
# better use SVG's instead:
|
||||
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
|
||||
<format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html
|
||||
;
|
||||
|
||||
using quickbook ;
|
||||
|
||||
path-constant boost-images : ../../../doc/src/images ;
|
||||
|
||||
xml declval : declval.qbk ;
|
||||
boostbook standalone
|
||||
:
|
||||
declval
|
||||
:
|
||||
# File name of HTML output:
|
||||
<xsl:param>root.filename=declval
|
||||
# How far down we chunk nested sections, basically all of them:
|
||||
<xsl:param>chunk.section.depth=0
|
||||
# Don't put the first section on the same page as the TOC:
|
||||
<xsl:param>chunk.first.sections=0
|
||||
# How far down sections get TOC's
|
||||
<xsl:param>toc.section.depth=1
|
||||
# Max depth in each TOC:
|
||||
<xsl:param>toc.max.depth=1
|
||||
# How far down we go with TOC's
|
||||
<xsl:param>generate.section.toc.level=1
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
104
doc/declval.qbk
104
doc/declval.qbk
@@ -1,104 +0,0 @@
|
||||
[/
|
||||
/ Copyright (c) 2008 Howard Hinnant
|
||||
/ Copyright (c) 2008 Beman Dawes
|
||||
/ Copyright (c) 2009-20010 Vicente J. Botet Escriba
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[article Declval
|
||||
[quickbook 1.5]
|
||||
[authors [Hinnant, Howard]]
|
||||
[authors [Dawes, Beman]]
|
||||
[authors [Botet Escriba, Vicente J.]]
|
||||
[copyright 2008 Howard Hinnant]
|
||||
[copyright 2008 Beman Dawes]
|
||||
[copyright 2009-2010 Vicente J. Botet Escriba]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||
]
|
||||
]
|
||||
|
||||
[/===============]
|
||||
[section Overview]
|
||||
[/===============]
|
||||
|
||||
The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958:
|
||||
Moving Swap Forward]. Here follows a rewording of this chapter.
|
||||
|
||||
With the provision of decltype, late-specified return types, and default template-arguments for function templates a
|
||||
new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale.
|
||||
Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration
|
||||
|
||||
template<class T>
|
||||
T&& declval(); // not used
|
||||
|
||||
as part of the function template declaration
|
||||
|
||||
template<class To, class From>
|
||||
decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
|
||||
or as part of a class template definition
|
||||
|
||||
template<class> class result_of;
|
||||
|
||||
template<class Fn, class... ArgTypes>
|
||||
struct result_of<Fn(ArgTypes...)>
|
||||
{
|
||||
typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
|
||||
};
|
||||
|
||||
The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function.
|
||||
The name is supposed to direct the reader's attention to the fact that the expression `declval<T>()` is an lvalue if and only if
|
||||
T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to
|
||||
|
||||
template<class T>
|
||||
typename std::add_rvalue_reference<T>::type declval(); // not used
|
||||
|
||||
which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()`
|
||||
already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C==0x standard.
|
||||
|
||||
The provision of a new library component that allows the production of values in unevaluated expressions is considered as
|
||||
important to realize constrained templates in C++0x where concepts are not available.
|
||||
This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[/=================]
|
||||
[section:reference Reference ]
|
||||
[/=================]
|
||||
|
||||
`#include <boost/utility/declval.hpp>`
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval();
|
||||
|
||||
[*Remarks:] If this function is used, the program is ill-formed.
|
||||
|
||||
[*Remarks:] The template parameter T of declval may be an incomplete type.
|
||||
|
||||
[*Example:]
|
||||
|
||||
template <class To, class From>
|
||||
decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
|
||||
Declares a function template convert which only participats in overloading if the type From can be explicitly converted to type To.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
@@ -1,163 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Declval</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.74.0">
|
||||
<link rel="home" href="declval.html" title="Declval">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"></div>
|
||||
<div class="article" lang="en">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div><h2 class="title">
|
||||
<a name="declval"></a>Declval</h2></div>
|
||||
<div><div class="authorgroup">
|
||||
<div class="author"><h3 class="author">
|
||||
<span class="firstname">Howard</span> <span class="surname">Hinnant</span>
|
||||
</h3></div>
|
||||
<div class="author"><h3 class="author">
|
||||
<span class="firstname">Beman</span> <span class="surname">Dawes</span>
|
||||
</h3></div>
|
||||
<div class="author"><h3 class="author">
|
||||
<span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span>
|
||||
</h3></div>
|
||||
</div></div>
|
||||
<div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div>
|
||||
<div><p class="copyright">Copyright © 2008 Beman Dawes</p></div>
|
||||
<div><p class="copyright">Copyright © 2009 -2010 Vicente J. Botet Escriba</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id879409"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="toc">
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl>
|
||||
<dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="declval.html#declval.reference"> Reference </a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.overview"></a><a class="link" href="declval.html#declval.overview" title="Overview">Overview</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
The motivation for <code class="computeroutput"><span class="identifier">declval</span></code>
|
||||
was introduced in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value" target="_top">N2958:
|
||||
Moving Swap Forward</a>. Here follows a rewording of this chapter.
|
||||
</p>
|
||||
<p>
|
||||
With the provision of decltype, late-specified return types, and default template-arguments
|
||||
for function templates a new generation of SFINAE patterns will emerge to at
|
||||
least partially compensate the lack of concepts on the C++0x timescale. Using
|
||||
this technique, it is sometimes necessary to obtain an object of a known type
|
||||
in a non-using context, e.g. given the declaration
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="identifier">T</span><span class="special">&&</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used
|
||||
</span></pre>
|
||||
<p>
|
||||
as part of the function template declaration
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span>
|
||||
<span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span>
|
||||
</pre>
|
||||
<p>
|
||||
or as part of a class template definition
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">></span> <span class="keyword">class</span> <span class="identifier">result_of</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">ArgTypes</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">result_of</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">(</span><span class="identifier">ArgTypes</span><span class="special">...)></span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">decltype</span><span class="special">(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">>()(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">ArgTypes</span><span class="special">>()...))</span> <span class="identifier">type</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
The role of the function template declval() is a transformation of a type T
|
||||
into a value without using or evaluating this function. The name is supposed
|
||||
to direct the reader's attention to the fact that the expression <code class="computeroutput"><span class="identifier">declval</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span></code> is
|
||||
an lvalue if and only if T is an lvalue-reference, otherwise an rvalue. To
|
||||
extend the domain of this function we can do a bit better by changing its declaration
|
||||
to
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</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">// not used
|
||||
</span></pre>
|
||||
<p>
|
||||
which ensures that we can also use cv void as template parameter. The careful
|
||||
reader might have noticed that <code class="computeroutput"><span class="identifier">declval</span><span class="special">()</span></code> already exists under the name create() as
|
||||
part of the definition of the semantics of the type trait is_convertible in
|
||||
the C==0x standard.
|
||||
</p>
|
||||
<p>
|
||||
The provision of a new library component that allows the production of values
|
||||
in unevaluated expressions is considered as important to realize constrained
|
||||
templates in C++0x where concepts are not available. This extremely light-weight
|
||||
function is expected to be part of the daily tool-box of the C++0x programmer.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.reference"></a><a class="link" href="declval.html#declval.reference" title="Reference"> Reference </a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
<code class="computeroutput"><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">declval</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">//noexcept; // as unevaluated operand
|
||||
</span>
|
||||
<span class="special">}</span> <span class="comment">// namespace boost
|
||||
</span></pre>
|
||||
<p>
|
||||
The library provides the function template declval to simplify the definition
|
||||
of expressions which occur as unevaluated operands.
|
||||
</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">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>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><strong>Remarks:</strong></span> If this function is used, the program
|
||||
is ill-formed.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>Remarks:</strong></span> The template parameter T of declval
|
||||
may be an incomplete type.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span>
|
||||
<span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Declares a function template convert which only participats in overloading
|
||||
if the type From can be explicitly converted to type To.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: September 16, 2010 at 16:19:10 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"></div>
|
||||
</body>
|
||||
</html>
|
111
enable_if.html
111
enable_if.html
@@ -21,7 +21,6 @@
|
||||
<BR>
|
||||
<BR>
|
||||
Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.<BR>
|
||||
Copyright 2011 Matt Calabrese.<BR>
|
||||
<BR>
|
||||
<!--TOC section Introduction-->
|
||||
|
||||
@@ -82,7 +81,7 @@ definitions to find this out. Instantiating the latter definition with
|
||||
<PRE>int::result_type negate(const int&);
|
||||
|
||||
</PRE>
|
||||
where the return type is invalid. If this were an error, adding an unrelated function template
|
||||
where the return type is invalid. If this was an error, adding an unrelated function template
|
||||
(that was never called) could break otherwise valid code.
|
||||
Due to the SFINAE principle the above example is not, however, erroneous.
|
||||
The latter definition of <TT>negate</TT> is simply removed from the overload resolution set.<BR>
|
||||
@@ -155,7 +154,6 @@ typename enable_if<boost::is_arithmetic<T>, T>::type
|
||||
foo(T t) { return t; }
|
||||
|
||||
</PRE>
|
||||
|
||||
<!--TOC section Using <TT>enable_if</TT>-->
|
||||
|
||||
<H2><A NAME="htoc5">3</A> Using <TT>enable_if</TT></H2><!--SEC END -->
|
||||
@@ -164,19 +162,8 @@ foo(T t) { return t; }
|
||||
The <TT>enable_if</TT> templates are defined in
|
||||
<TT>boost/utility/enable_if.hpp</TT>, which is included by <TT>boost/utility.hpp</TT>.<BR>
|
||||
<BR>
|
||||
With respect to function templates, <TT>enable_if</TT> can be used in multiple different ways:
|
||||
|
||||
<UL>
|
||||
<LI>As the return type of an instantiatied function
|
||||
<LI>As an extra parameter of an instantiated function
|
||||
<LI>As an extra template parameter (useful only in a compiler that supports C++0x default
|
||||
arguments for function template parameters, see <A href="#sec:enable_if_0x">Enabling function
|
||||
templates in C++0x</a> for details)
|
||||
</UL>
|
||||
|
||||
In the previous section, the return type form of <TT>enable_if</TT> was shown. As an example
|
||||
of using the form of <TT>enable_if</TT> that works via an extra function parameter, the
|
||||
<TT>foo</TT> function in the previous section could also be written
|
||||
The <TT>enable_if</TT> template can be used either as the return type, or as an
|
||||
extra argument. For example, the <TT>foo</TT> function in the previous section could also be written
|
||||
as:
|
||||
<PRE>template <class T>
|
||||
T foo(T t, typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0);
|
||||
@@ -186,80 +173,18 @@ a default value to keep the parameter hidden from client code.
|
||||
Note that the second template argument was not given to <TT>enable_if</TT>, as the default
|
||||
<TT>void</TT> gives the desired behavior.<BR>
|
||||
<BR>
|
||||
Which way to write the enabler is largely a matter of taste, but for certain functions, only a
|
||||
subset of the options is possible:
|
||||
Whether to write the enabler as an argument or within the return type is
|
||||
largely a matter of taste, but for certain functions, only one
|
||||
alternative is possible:
|
||||
<UL><LI>
|
||||
Many operators have a fixed number of arguments, thus <TT>enable_if</TT> must be used either in the
|
||||
return type or in an extra template parameter.
|
||||
<LI>Functions that have a variadic parameter list must use either the return type form or an extra
|
||||
template parameter.
|
||||
<LI>Constructors do not have a return type so you must use either an extra function parameter or an
|
||||
extra template parameter.
|
||||
<LI>Constructors that have a variadic parameter list must an extra template parameter.
|
||||
<LI>Conversion operators can only be written with an extra template parameter.
|
||||
Operators have a fixed number of arguments, thus <TT>enable_if</TT> must be used in the return type.
|
||||
<LI>Constructors and destructors do not have a return type; an extra argument is the only option.
|
||||
<LI>There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors,
|
||||
however, can have enablers as extra default arguments.
|
||||
</UL>
|
||||
<!--TOC subsection Enabling function templates in C++0x-->
|
||||
|
||||
<A NAME="sec:enable_if_0x"></A>
|
||||
<H3><A NAME="htoc7">3.1</A> Enabling function templates in C++0x</H3><!--SEC END -->
|
||||
|
||||
In a compiler which supports C++0x default arguments for function template parameters, you can
|
||||
enable and disable function templates by adding an additional template parameter. This approach
|
||||
works in all situations where you would use either the return type form of <TT>enable_if</TT> or
|
||||
the function parameter form, including operators, constructors, variadic function templates, and
|
||||
even overloaded conversion operations.
|
||||
|
||||
As an example:
|
||||
|
||||
<PRE>#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
class test
|
||||
{
|
||||
public:
|
||||
// A constructor that works for any argument list of size 10
|
||||
template< class... T
|
||||
, typename boost::enable_if_c< sizeof...( T ) == 10, int >::type = 0
|
||||
>
|
||||
test( T&&... );
|
||||
|
||||
// A conversion operation that can convert to any arithmetic type
|
||||
template< class T
|
||||
, typename boost::enable_if< boost::is_arithmetic< T >, int >::type = 0
|
||||
>
|
||||
operator T() const;
|
||||
|
||||
// A conversion operation that can convert to any pointer type
|
||||
template< class T
|
||||
, typename boost::enable_if< boost::is_pointer< T >, int >::type = 0
|
||||
>
|
||||
operator T() const;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Works
|
||||
test test_( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 );
|
||||
|
||||
// Fails as expected
|
||||
test fail_construction( 1, 2, 3, 4, 5 );
|
||||
|
||||
// Works by calling the conversion operator enabled for arithmetic types
|
||||
int arithmetic_object = test_;
|
||||
|
||||
// Works by calling the conversion operator enabled for pointer types
|
||||
int* pointer_object = test_;
|
||||
|
||||
// Fails as expected
|
||||
struct {} fail_conversion = test_;
|
||||
}
|
||||
|
||||
</PRE>
|
||||
|
||||
<!--TOC subsection Enabling template class specializations-->
|
||||
|
||||
<H3><A NAME="htoc7">3.2</A> Enabling template class specializations</H3><!--SEC END -->
|
||||
<H3><A NAME="htoc6">3.1</A> Enabling template class specializations</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:enable_if_classes"></A>
|
||||
Class template specializations can be enabled or disabled with <TT>enable_if</TT>.
|
||||
@@ -285,7 +210,7 @@ is the correct value.<BR>
|
||||
<BR>
|
||||
<!--TOC subsection Overlapping enabler conditions-->
|
||||
|
||||
<H3><A NAME="htoc8">3.3</A> Overlapping enabler conditions</H3><!--SEC END -->
|
||||
<H3><A NAME="htoc7">3.2</A> Overlapping enabler conditions</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:overlapping_conditions"></A>
|
||||
Once the compiler has examined the enabling conditions and included the
|
||||
@@ -314,7 +239,7 @@ partial specializations as well.<BR>
|
||||
<BR>
|
||||
<!--TOC subsection Lazy <TT>enable_if</TT>-->
|
||||
|
||||
<H3><A NAME="htoc9">3.4</A> Lazy <TT>enable_if</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc8">3.3</A> Lazy <TT>enable_if</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:enable_if_lazy"></A>
|
||||
In some cases it is necessary to avoid instantiating part of a
|
||||
@@ -360,7 +285,7 @@ above example, <TT>is_multipliable<T, U>::value</TT> defines when
|
||||
<BR>
|
||||
<!--TOC subsection Compiler workarounds-->
|
||||
|
||||
<H3><A NAME="htoc10">3.5</A> Compiler workarounds</H3><!--SEC END -->
|
||||
<H3><A NAME="htoc9">3.4</A> Compiler workarounds</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:workarounds"></A>
|
||||
Some compilers flag functions as ambiguous if the only distinguishing factor is a different
|
||||
@@ -442,9 +367,9 @@ David Vandevoorde and Nicolai M. Josuttis.
|
||||
Addison-Wesley, 2002.</DL>
|
||||
|
||||
<hr/>
|
||||
<p>Copyright Jaakko Järvi<sup>*</sup>, Jeremiah Willcock<sup>*</sup>, Andrew Lumsdaine<sup>*</sup>, Matt Calabrese<BR>
|
||||
<EM>{jajarvi|jewillco|lums}@osl.iu.edu, rivorus@gmail.com</EM><BR>
|
||||
<sup>*</sup>Indiana University<BR>
|
||||
<p>Copyright Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine<BR>
|
||||
<EM>{jajarvi|jewillco|lums}@osl.iu.edu</EM><BR>
|
||||
Indiana University<BR>
|
||||
Open Systems Lab<br/>
|
||||
Use, modification and distribution are subject to the
|
||||
Boost Software License, Version 1.0.
|
||||
@@ -461,4 +386,4 @@ or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.
|
||||
</EM></BLOCKQUOTE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
</HTML>
|
@@ -1,11 +1,8 @@
|
||||
//
|
||||
// boost/assert.hpp - BOOST_ASSERT(expr)
|
||||
// BOOST_ASSERT_MSG(expr, msg)
|
||||
// BOOST_VERIFY(expr)
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
// Copyright (c) Beman Dawes 2011
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,16 +13,6 @@
|
||||
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
||||
//
|
||||
|
||||
//
|
||||
// Stop inspect complaining about use of 'assert':
|
||||
//
|
||||
// boostinspect:naassert_macro
|
||||
//
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_ASSERT //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#undef BOOST_ASSERT
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS)
|
||||
@@ -38,86 +25,18 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
void assertion_failed(char const * expr,
|
||||
char const * function, char const * file, long line); // user defined
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT(expr) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
|
||||
# define BOOST_ASSERT(expr) assert(expr)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_ASSERT_MSG //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
# undef BOOST_ASSERT_MSG
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((void)0)
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
void assertion_failed_msg(char const * expr, char const * msg,
|
||||
char const * function, char const * file, long line); // user defined
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
#ifndef BOOST_ASSERT_HPP
|
||||
#define BOOST_ASSERT_HPP
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
// IDE's like Visual Studio perform better if output goes to std::cout or
|
||||
// some other stream, so allow user to configure output stream:
|
||||
#ifndef BOOST_ASSERT_MSG_OSTREAM
|
||||
# define BOOST_ASSERT_MSG_OSTREAM std::cerr
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace assertion
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline void assertion_failed_msg(char const * expr, char const * msg, char const * function,
|
||||
char const * file, long line)
|
||||
{
|
||||
BOOST_ASSERT_MSG_OSTREAM
|
||||
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
||||
<< function << ":\n"
|
||||
<< file << '(' << line << "): " << msg << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
} // detail
|
||||
} // assertion
|
||||
} // detail
|
||||
#endif
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
|
||||
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_VERIFY //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#undef BOOST_VERIFY
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
|
||||
|
@@ -28,7 +28,7 @@ namespace detail
|
||||
inline void current_function_helper()
|
||||
{
|
||||
|
||||
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
|
||||
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600))
|
||||
|
||||
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
|
||||
|
||||
@@ -65,4 +65,3 @@ inline void current_function_helper()
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
|
||||
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||
|
||||
// Revision History
|
||||
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||
// (Matthew Bradbury, fixes #4432)
|
||||
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||
// for T::operator<, etc. (Daniel Frey)
|
||||
@@ -90,7 +88,7 @@
|
||||
# pragma set woff 1234
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||
#endif // operator-> not begin a UDT
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@@ -1,44 +0,0 @@
|
||||
// common_type.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright 2010 Vicente J. Botet Escriba
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// C++03 implementation of //
|
||||
// Written by Vicente J. Botet Escriba //
|
||||
//~ 20.3.4 Function template declval [declval]
|
||||
//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as
|
||||
//~ unevaluated operands.
|
||||
//~ 2 Remarks: If this function is used, the program is ill-formed.
|
||||
//~ 3 Remarks: The template parameter T of declval may be an incomplete type.
|
||||
//~ [ Example:
|
||||
|
||||
//~ template <class To, class From>
|
||||
//~ decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
|
||||
//~ declares a function template convert which only participats in overloading if the type From can be
|
||||
//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). <20>end
|
||||
//~ example ]
|
||||
// //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
@@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@@ -10,6 +10,47 @@
|
||||
# error Boost result_of - do not include this file!
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
|
||||
// As of N2588, C++0x result_of only supports function call
|
||||
// expressions of the form f(x). This precludes support for member
|
||||
// function pointers, which are invoked with expressions of the form
|
||||
// o->*f(x). This implementation supports both.
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, detail::result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||
>
|
||||
, detail::result_of_decltype_impl<
|
||||
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \
|
||||
static T ## n t ## n; \
|
||||
/**/
|
||||
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
class result_of_decltype_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
{
|
||||
static F f;
|
||||
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
|
||||
public:
|
||||
typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else // defined(BOOST_HAS_DECLTYPE)
|
||||
|
||||
// CWPro8 requires an argument in a function type specialization
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
||||
# define BOOST_RESULT_OF_ARGS void
|
||||
@@ -20,79 +61,37 @@
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
, boost::detail::result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)>
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
, boost::detail::result_of_impl<
|
||||
F,
|
||||
F(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)> >::type { };
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
|
||||
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, detail::tr1_result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||
>
|
||||
, detail::cpp0x_result_of_impl<
|
||||
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
{
|
||||
typedef decltype(
|
||||
boost::declval<F>()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<T, >() BOOST_PP_INTERCEPT)
|
||||
)
|
||||
) type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||
#endif
|
||||
|
||||
#endif // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
|
||||
#endif // defined(BOOST_HAS_DECLTYPE)
|
||||
|
||||
#if BOOST_PP_ITERATION() >= 1
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
struct result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
@@ -100,7 +99,7 @@ struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), F
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
struct result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
FArgs, false>
|
||||
{
|
||||
@@ -109,7 +108,7 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
struct result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const,
|
||||
FArgs, false>
|
||||
@@ -119,7 +118,7 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
struct result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
volatile,
|
||||
FArgs, false>
|
||||
@@ -129,7 +128,7 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
struct result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const volatile,
|
||||
FArgs, false>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@@ -13,9 +13,7 @@
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
@@ -24,7 +22,6 @@
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
|
||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
@@ -33,15 +30,14 @@
|
||||
namespace boost {
|
||||
|
||||
template<typename F> struct result_of;
|
||||
template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
namespace detail {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
||||
template<typename F> struct cpp0x_result_of_impl;
|
||||
template<typename F, typename FArgs, bool HasResultType> struct result_of_impl;
|
||||
template<typename F> struct result_of_decltype_impl;
|
||||
|
||||
template<typename F>
|
||||
struct result_of_void_impl
|
||||
@@ -64,10 +60,10 @@ struct result_of_void_impl<R (&)(void)>
|
||||
// Determine the return type of a function pointer or pointer to member.
|
||||
template<typename F, typename FArgs>
|
||||
struct result_of_pointer
|
||||
: tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
||||
: result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct tr1_result_of_impl<F, FArgs, true>
|
||||
struct result_of_impl<F, FArgs, true>
|
||||
{
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
@@ -83,7 +79,7 @@ struct result_of_nested_result : F::template result<FArgs>
|
||||
{};
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct tr1_result_of_impl<F, FArgs, false>
|
||||
struct result_of_impl<F, FArgs, false>
|
||||
: mpl::if_<is_function_with_no_args<FArgs>,
|
||||
result_of_void_impl<F>,
|
||||
result_of_nested_result<F, FArgs> >::type
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@@ -9,8 +9,6 @@
|
||||
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
||||
// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
|
||||
// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
|
||||
// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
|
||||
// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker
|
||||
//
|
||||
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||
@@ -22,7 +20,6 @@
|
||||
// contains. More details on these issues are at libs/utility/value_init.htm
|
||||
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
@@ -31,39 +28,10 @@
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER >= 1310
|
||||
// It is safe to ignore the following warning from MSVC 7.1 or higher:
|
||||
// "warning C4351: new behavior: elements of array will be default initialized"
|
||||
#pragma warning(disable: 4351)
|
||||
// It is safe to ignore the following MSVC warning, which may pop up when T is
|
||||
// a const type: "warning C4512: assignment operator could not be generated".
|
||||
#pragma warning(disable: 4512)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
|
||||
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
// suggests that a workaround should be applied, because of compiler issues
|
||||
// regarding value-initialization.
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
#endif
|
||||
|
||||
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
// switches the value-initialization workaround either on or off.
|
||||
#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
|
||||
#else
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
class initialized
|
||||
class value_initialized
|
||||
{
|
||||
private :
|
||||
struct wrapper
|
||||
@@ -72,18 +40,6 @@ class initialized
|
||||
typename
|
||||
#endif
|
||||
remove_const<T>::type data;
|
||||
|
||||
wrapper()
|
||||
:
|
||||
data()
|
||||
{
|
||||
}
|
||||
|
||||
wrapper(T const & arg)
|
||||
:
|
||||
data(arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
mutable
|
||||
@@ -99,25 +55,30 @@ class initialized
|
||||
|
||||
public :
|
||||
|
||||
initialized()
|
||||
value_initialized()
|
||||
{
|
||||
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
std::memset(&x, 0, sizeof(x));
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER >= 1310
|
||||
// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345:
|
||||
// "behavior change: an object of POD type constructed with an initializer of the form ()
|
||||
// will be default-initialized". It is safe to ignore this warning when using value_initialized.
|
||||
#pragma warning(disable: 4345)
|
||||
#endif
|
||||
#endif
|
||||
new (wrapper_address()) wrapper();
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
initialized(initialized const & arg)
|
||||
value_initialized(value_initialized const & arg)
|
||||
{
|
||||
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
||||
}
|
||||
|
||||
explicit initialized(T const & arg)
|
||||
{
|
||||
new (wrapper_address()) wrapper(arg);
|
||||
}
|
||||
|
||||
initialized & operator=(initialized const & arg)
|
||||
value_initialized & operator=(value_initialized const & arg)
|
||||
{
|
||||
// Assignment is only allowed when T is non-const.
|
||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||
@@ -125,7 +86,7 @@ class initialized
|
||||
return *this;
|
||||
}
|
||||
|
||||
~initialized()
|
||||
~value_initialized()
|
||||
{
|
||||
wrapper_address()->wrapper::~wrapper();
|
||||
}
|
||||
@@ -140,81 +101,17 @@ class initialized
|
||||
return wrapper_address()->data;
|
||||
}
|
||||
|
||||
void swap(initialized & arg)
|
||||
void swap(value_initialized & arg)
|
||||
{
|
||||
::boost::swap( this->data(), arg.data() );
|
||||
}
|
||||
|
||||
operator T const &() const
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
}
|
||||
operator T const &() const { return this->data(); }
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
}
|
||||
operator T&() { return this->data(); }
|
||||
|
||||
} ;
|
||||
|
||||
template<class T>
|
||||
T const& get ( initialized<T> const& x )
|
||||
{
|
||||
return x.data() ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& get ( initialized<T>& x )
|
||||
{
|
||||
return x.data() ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void swap ( initialized<T> & lhs, initialized<T> & rhs )
|
||||
{
|
||||
lhs.swap(rhs) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class value_initialized
|
||||
{
|
||||
private :
|
||||
|
||||
// initialized<T> does value-initialization by default.
|
||||
initialized<T> m_data;
|
||||
|
||||
public :
|
||||
|
||||
value_initialized()
|
||||
:
|
||||
m_data()
|
||||
{ }
|
||||
|
||||
T const & data() const
|
||||
{
|
||||
return m_data.data();
|
||||
}
|
||||
|
||||
T& data()
|
||||
{
|
||||
return m_data.data();
|
||||
}
|
||||
|
||||
void swap(value_initialized & arg)
|
||||
{
|
||||
m_data.swap(arg.m_data);
|
||||
}
|
||||
|
||||
operator T const &() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
template<class T>
|
||||
@@ -222,7 +119,6 @@ T const& get ( value_initialized<T> const& x )
|
||||
{
|
||||
return x.data() ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& get ( value_initialized<T>& x )
|
||||
{
|
||||
@@ -242,7 +138,7 @@ class initialized_value_t
|
||||
|
||||
template <class T> operator T() const
|
||||
{
|
||||
return initialized<T>().data();
|
||||
return get( value_initialized<T>() );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -251,8 +147,5 @@ initialized_value_t const initialized_value = {} ;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -20,7 +20,6 @@
|
||||
<a href="checked_delete.html">checked_delete</a><br>
|
||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||
<a href="current_function.html">current_function</a><br>
|
||||
<a href="doc/html/declval.html">declval</a><br>
|
||||
<a href="enable_if.html">enable_if</a><br>
|
||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||
@@ -41,4 +40,3 @@
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@@ -1,116 +0,0 @@
|
||||
// Copyright 2010, Niels Dekker.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Test program for boost::initialized<T>.
|
||||
//
|
||||
// 2 May 2010 (Created) Niels Dekker
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
// Typical use case for boost::initialized<T>: A generic class that
|
||||
// holds a value of type T, which must be initialized by either
|
||||
// value-initialization or direct-initialization.
|
||||
template <class T> class key_value_pair
|
||||
{
|
||||
std::string m_key;
|
||||
boost::initialized<T> m_value;
|
||||
public:
|
||||
|
||||
// Value-initializes the object held by m_value.
|
||||
key_value_pair() { }
|
||||
|
||||
// Value-initializes the object held by m_value.
|
||||
explicit key_value_pair(const std::string& key)
|
||||
:
|
||||
m_key(key)
|
||||
{
|
||||
}
|
||||
|
||||
// Direct-initializes the object held by m_value.
|
||||
key_value_pair(const std::string& key, const T& value)
|
||||
:
|
||||
m_key(key), m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
const T& get_value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Tells whether the argument is value-initialized.
|
||||
bool is_value_initialized(const int& arg)
|
||||
{
|
||||
return arg == 0;
|
||||
}
|
||||
|
||||
|
||||
// Tells whether the argument is value-initialized.
|
||||
bool is_value_initialized(const std::string& arg)
|
||||
{
|
||||
return arg.empty();
|
||||
}
|
||||
|
||||
struct foo
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
bool operator==(const foo& lhs, const foo& rhs)
|
||||
{
|
||||
return lhs.data == rhs.data;
|
||||
}
|
||||
|
||||
|
||||
// Tells whether the argument is value-initialized.
|
||||
bool is_value_initialized(const foo& arg)
|
||||
{
|
||||
return arg.data == 0;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void test_key_value_pair(const T& magic_value)
|
||||
{
|
||||
// The value component of a default key_value_pair must be value-initialized.
|
||||
key_value_pair<T> default_key_value_pair;
|
||||
BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) );
|
||||
|
||||
// The value component of a key_value_pair that only has its key explicitly specified
|
||||
// must also be value-initialized.
|
||||
BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) );
|
||||
|
||||
// However, the value component of the following key_value_pair must be
|
||||
// "magic_value", as it must be direct-initialized.
|
||||
BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tests boost::initialize for a fundamental type, a type with a
|
||||
// user-defined constructor, and a user-defined type without
|
||||
// a user-defined constructor.
|
||||
int main()
|
||||
{
|
||||
|
||||
const int magic_number = 42;
|
||||
test_key_value_pair(magic_number);
|
||||
|
||||
const std::string magic_string = "magic value";
|
||||
test_key_value_pair(magic_string);
|
||||
|
||||
const foo magic_foo = { 42 };
|
||||
test_key_value_pair(magic_foo);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
// Copyright 2010, Niels Dekker.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Test program for boost::initialized<T>. Must fail to compile.
|
||||
//
|
||||
// Initial: 2 May 2010
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
void direct_initialize_from_int()
|
||||
{
|
||||
// Okay: initialized<T> supports direct-initialization from T.
|
||||
boost::initialized<int> direct_initialized_int(1);
|
||||
}
|
||||
|
||||
void copy_initialize_from_int()
|
||||
{
|
||||
// The following line should not compile, because initialized<T>
|
||||
// was not intended to supports copy-initialization from T.
|
||||
boost::initialized<int> copy_initialized_int = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// This should fail to compile, so there is no need to call any function.
|
||||
return 0;
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
// Copyright 2010, Niels Dekker.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Test program for boost::initialized<T>. Must fail to compile.
|
||||
//
|
||||
// Initial: 2 May 2010
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
void from_value_initialized_to_initialized()
|
||||
{
|
||||
boost::value_initialized<int> value_initialized_int;
|
||||
|
||||
// Okay: initialized<T> can be initialized by value_initialized<T>.
|
||||
boost::initialized<int> initialized_int(value_initialized_int);
|
||||
}
|
||||
|
||||
void from_initialized_to_value_initialized()
|
||||
{
|
||||
boost::initialized<int> initialized_int(13);
|
||||
|
||||
// The following line should not compile, because initialized<T>
|
||||
// should not be convertible to value_initialized<T>.
|
||||
boost::value_initialized<int> value_initialized_int(initialized_int);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// This should fail to compile, so there is no need to call any function.
|
||||
return 0;
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2008 - 2010 Joseph Gauterin, Niels Dekker
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,8 +17,8 @@
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
typedef std::bitset<8> bitset_type;
|
||||
const bitset_type initial_value1 = 1;
|
||||
const bitset_type initial_value2 = 2;
|
||||
const bitset_type initial_value1 = 1ul;
|
||||
const bitset_type initial_value2 = 2ul;
|
||||
|
||||
bitset_type object1 = initial_value1;
|
||||
bitset_type object2 = initial_value2;
|
||||
|
@@ -32,13 +32,9 @@ test-suite utility
|
||||
[ compile result_of_test.cpp ]
|
||||
[ run ../shared_iterator_test.cpp ]
|
||||
[ run ../value_init_test.cpp ]
|
||||
[ run ../value_init_workaround_test.cpp ]
|
||||
[ run ../initialized_test.cpp ]
|
||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||
[ run ../verify_test.cpp ]
|
||||
;
|
||||
|
||||
|
@@ -5,8 +5,6 @@
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <utility>
|
||||
@@ -98,11 +96,6 @@ struct no_result_type_or_result_of
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -113,11 +106,6 @@ struct no_result_type_or_result_of_template
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct X {};
|
||||
@@ -143,21 +131,9 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
|
||||
// Prior to decltype, result_of could not deduce the return type
|
||||
// nullary function objects unless they exposed a result_type.
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
|
||||
@@ -169,14 +145,11 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
|
||||
|
||||
// Prior to decltype, result_of ignored a nested result<> if
|
||||
// result_type was defined. After decltype, result_of deduces the
|
||||
// actual return type of the function object, ignoring both
|
||||
// result<> and result_type.
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
|
||||
#else
|
||||
@@ -195,17 +168,6 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
@@ -215,23 +177,11 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
|
||||
|
||||
typedef int (*pf_t)(int);
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
|
||||
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(void)>::type, unsigned int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of(double)>::type, short>::value));
|
||||
@@ -242,14 +192,6 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value));
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int const&)>::type, long>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int const&)>::type, long>::value));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
112
utility.htm
112
utility.htm
@@ -151,109 +151,37 @@ void f() {
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> defines the result type
|
||||
of the expression <code>f(t1, t2,
|
||||
...,t<em>N</em>)</code>. This implementation permits
|
||||
...,t<em>N</em>)</code>. The implementation permits
|
||||
the type <code>F</code> to be a function pointer,
|
||||
function reference, member function pointer, or class
|
||||
type. By default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>. Class template <code>result_of</code>
|
||||
resides in the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
|
||||
<p>If your compiler supports <code>decltype</code>,
|
||||
then you can enable automatic result type deduction by
|
||||
defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>,
|
||||
as in the following example.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
struct functor {
|
||||
template<class T>
|
||||
T operator()(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>If <code>decltype</code> is not enabled,
|
||||
then automatic result type deduction of function
|
||||
objects is not possible. Instead, <code>result_of</code>
|
||||
uses the following protocol to allow the programmer to
|
||||
specify a type. When <code>F</code> is a class type with a
|
||||
member type <code>result_type</code>,
|
||||
type.</p> <p>If your compiler does not support
|
||||
<code>decltype</code>, then when <code>F</code> is a
|
||||
class type with a member type <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is
|
||||
<code>F::result_type</code>. When <code>F</code> does
|
||||
not contain <code>result_type</code>,
|
||||
<code>F::result_type</code>. When <code>F</code>
|
||||
does not contain <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||
T2, ..., T<em>N</em>)>::type</code> when
|
||||
<code><em>N</em> > 0</code> or <code>void</code>
|
||||
when <code><em>N</em> = 0</code>. Note that it is the
|
||||
responsibility of the programmer to ensure that
|
||||
function objects accurately advertise their result
|
||||
type via this protocol, as in the following
|
||||
example.</p>
|
||||
when <code><em>N</em> = 0</code>. For additional
|
||||
information about <code>result_of</code>, see the
|
||||
C++ Library Technical Report, <a
|
||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
||||
or, for motivation and design rationale, the <code>result_of</code> <a
|
||||
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result;
|
||||
|
||||
template<class F, class T>
|
||||
struct result<F(T)> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T operator()(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>In a future
|
||||
release, <code>BOOST_RESULT_OF_USE_DECLTYPE</code>
|
||||
may be enabled by default on compilers that
|
||||
support <code>decltype</code>, so if you use the above
|
||||
protocol please take care to ensure that
|
||||
the <code>result_type</code>
|
||||
and <code>result<></code> members accurately
|
||||
represent the result type. If you wish to continue to
|
||||
use the protocol on compilers that
|
||||
support <code>decltype</code>,
|
||||
use <code>boost::tr1_result_of</code>, which is also
|
||||
defined
|
||||
in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
<p>Class template <code>result_of</code> resides in
|
||||
the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
|
||||
default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>.</p>
|
||||
|
||||
<a name="BOOST_NO_RESULT_OF"></a>
|
||||
<p>This implementation of <code>result_of</code>
|
||||
requires class template partial specialization, the
|
||||
ability to parse function types properly, and support
|
||||
for SFINAE. If <code>result_of</code> is not supported
|
||||
by your compiler, including the header
|
||||
<code>boost/utility/result_of.hpp</code> will
|
||||
define the macro <code>BOOST_NO_RESULT_OF</code>.</p>
|
||||
|
||||
<p>For additional information
|
||||
about <code>result_of</code>, see the C++ Library
|
||||
Technical Report,
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
||||
or, for motivation and design rationale,
|
||||
the <code>result_of</code> <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
||||
Contributed by Doug Gregor.</p>
|
||||
<p>This implementation of <code>result_of</code> requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. If <code>result_of</code> is not supported by your compiler, including the header <code>boost/utility/result_of.hpp</code> will define the macro <code>BOOST_NO_RESULT_OF</code>. Contributed by Doug Gregor.</p>
|
||||
|
||||
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||
|
140
value_init.htm
140
value_init.htm
@@ -33,7 +33,6 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
||||
<li><a href="#initialized"><code>template class initialized<T></code></a></li>
|
||||
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||
|
||||
</ul>
|
||||
@@ -124,12 +123,6 @@ constructed by the following declaration:
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
The template <a href="#initialized"><code>initialized</code></a>
|
||||
offers both value-initialization and direct-initialization.
|
||||
It is especially useful as a data member type, allowing the very same object
|
||||
to be either direct-initialized or value-initialized.
|
||||
</p>
|
||||
<p>
|
||||
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||
allows value-initializing a variable as follows:
|
||||
<pre>
|
||||
@@ -223,65 +216,37 @@ it <em>may</em> in practice still be left uninitialized, because of those
|
||||
compiler issues! It's hard to make a general statement on what those issues
|
||||
are like, because they depend on the compiler you are using, its version number,
|
||||
and the type of object you would like to have value-initialized.
|
||||
All compilers we have tested so far support value-initialization for arithmetic types properly.
|
||||
However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
|
||||
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
|
||||
go wrong on various compilers.
|
||||
Compilers usually support value-initialization for built-in types properly.
|
||||
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
|
||||
be partially, or even entirely left uninitialized, when they should be value-initialized.
|
||||
</p>
|
||||
<p>
|
||||
At the moment of writing, May 2010, the following reported issues regarding
|
||||
value-initialization are still there in current compiler releases:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
|
||||
Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
|
||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
|
||||
</li><li>
|
||||
<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
|
||||
Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
|
||||
<br>Reported by Sylvester Hesp, 2009
|
||||
</li><li>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
|
||||
Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
|
||||
<br>Reported by Alex Vakulenko, 2009
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
|
||||
Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
|
||||
<br>Reported by Niels Dekker (LKEB), 2010
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851">
|
||||
Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a>
|
||||
<br>Reported by Niels Dekker, 2010
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279">
|
||||
Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a>
|
||||
<br>Reported by Niels Dekker, 2010
|
||||
</li><li>
|
||||
Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate.
|
||||
<br>Reported to Steve Clamage by Niels Dekker, 2010
|
||||
</li><li>
|
||||
IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate.
|
||||
<br>Reported to Michael Wong by Niels Dekker, 2010
|
||||
</li><li>
|
||||
Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error
|
||||
on Intel 11.1.
|
||||
<br>Reported by John Maddock, 2010
|
||||
</li>
|
||||
</ul>
|
||||
Note that all known GCC issues regarding value-initialization are
|
||||
fixed with GCC version 4.4, including
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>.
|
||||
Clang also has completely implemented value-initialization, as far as we know,
|
||||
now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.
|
||||
We have encountered issues regarding value-initialization on compilers by
|
||||
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
|
||||
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
|
||||
<tr><td>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
|
||||
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
|
||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
|
||||
<br>
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
|
||||
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
|
||||
<br>Reported by Jonathan Wakely, 2006-12-07
|
||||
<br>
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
|
||||
GCC Bug 33916 - Default constructor fails to initialize array members</a>
|
||||
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
|
||||
<br>
|
||||
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
|
||||
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
|
||||
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
|
||||
<br>
|
||||
</td></tr></table>
|
||||
</p><p>
|
||||
|
||||
New versions of <code>value_initialized</code>
|
||||
(Boost release version 1.35 or higher)
|
||||
offer a workaround to these issues: <code>value_initialized</code> may now clear
|
||||
its internal data, prior to constructing the object that it contains. It will do
|
||||
so for those compilers that need to have such a workaround, based on the
|
||||
<a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects"
|
||||
>compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||
offer a workaround to these issues: <code>value_initialized</code> will now clear
|
||||
its internal data, prior to constructing the object that it contains.
|
||||
</p>
|
||||
|
||||
<h2><a name="types"></a>Types and objects</h2>
|
||||
@@ -375,52 +340,6 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
||||
|
||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
||||
|
||||
<h2><a name="initialized"><code>template class initialized<T></code></a></h2>
|
||||
|
||||
<pre>namespace boost {<br><br>template<class T><br>class initialized<br>{
|
||||
<br> public :
|
||||
<br> initialized() : x() {}
|
||||
<br> explicit initialized(T const & arg) : x(arg) {}
|
||||
<br> operator T const &() const;
|
||||
<br> operator T&();
|
||||
<br> T const &data() const;
|
||||
<br> T& data();
|
||||
<br> void swap( value_initialized<T>& );
|
||||
<br>
|
||||
<br> private :
|
||||
<br> <i>unspecified</i> x ;
|
||||
<br>} ;
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T const& get ( initialized<T> const& x );
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T& get ( initialized<T>& x );
|
||||
<br>
|
||||
<br>} // namespace boost
|
||||
<br></pre>
|
||||
|
||||
The template class <code>boost::initialized<T></code> supports both value-initialization
|
||||
and direct-initialization, so its interface is a superset of the interface
|
||||
of <code>value_initialized<T></code>: Its default-constructor
|
||||
value-initializes the wrapped object just like the default-constructor of
|
||||
<code>value_initialized<T></code>, but <code>boost::initialized<T></code>
|
||||
also offers an extra <code>explicit</code>
|
||||
constructor, which direct-initializes the wrapped object by the specified value.
|
||||
<p>
|
||||
|
||||
<code>initialized<T></code> is especially useful when the wrapped
|
||||
object must be either value-initialized or direct-initialized, depending on
|
||||
runtime conditions. For example, <code>initialized<T></code> could
|
||||
hold the value of a data member that may be value-initialized by some
|
||||
constructors, and direct-initialized by others.
|
||||
On the other hand, if it is known beforehand that the
|
||||
object must <i>always</i> be value-initialized, <code>value_initialized<T></code>
|
||||
may be preferable. And if the object must always be
|
||||
direct-initialized, none of the two wrappers really needs to be used.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||
|
||||
<pre>
|
||||
@@ -480,9 +399,6 @@ Special thanks to Björn Karlsson who carefully edited and completed this do
|
||||
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
||||
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||
</p>
|
||||
<p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
|
||||
Jeffrey Hellrung.
|
||||
</p>
|
||||
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||
</p>
|
||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
||||
@@ -491,9 +407,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>Revised 30 May 2010</p>
|
||||
<p>Revised 03 October 2009</p>
|
||||
|
||||
<p>© Copyright Fernando Cacciola, 2002 - 2010.</p>
|
||||
<p>© Copyright Fernando Cacciola, 2002, 2009.</p>
|
||||
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||
|
@@ -1,144 +0,0 @@
|
||||
// Copyright 2010, Niels Dekker.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Test program for the boost::value_initialized<T> workaround.
|
||||
//
|
||||
// 17 June 2010 (Created) Niels Dekker
|
||||
|
||||
// Switch the workaround off, before inluding "value_init.hpp".
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
|
||||
#include <boost/utility/value_init.hpp>
|
||||
|
||||
#include <iostream> // For cout.
|
||||
#include <cstdlib> // For EXIT_SUCCESS and EXIT_FAILURE.
|
||||
|
||||
namespace
|
||||
{
|
||||
struct empty_struct
|
||||
{
|
||||
};
|
||||
|
||||
// A POD aggregate struct derived from an empty struct.
|
||||
// Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
|
||||
// "VC++ does not value-initialize members of derived classes without
|
||||
// user-declared constructor", reported in 2009 by Sylvester Hesp:
|
||||
// https://connect.microsoft.com/VisualStudio/feedback/details/484295
|
||||
struct derived_struct: empty_struct
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
bool is_value_initialized(const derived_struct& arg)
|
||||
{
|
||||
return arg.data == 0;
|
||||
}
|
||||
|
||||
|
||||
class virtual_destructor_holder
|
||||
{
|
||||
public:
|
||||
int i;
|
||||
virtual ~virtual_destructor_holder()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
bool is_value_initialized(const virtual_destructor_holder& arg)
|
||||
{
|
||||
return arg.i == 0;
|
||||
}
|
||||
|
||||
// Equivalent to the Stats class from GCC Bug 33916,
|
||||
// "Default constructor fails to initialize array members", reported in 2007 by
|
||||
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
|
||||
// and fixed for GCC 4.2.4.
|
||||
class private_int_array_pair
|
||||
{
|
||||
friend bool is_value_initialized(const private_int_array_pair& arg);
|
||||
private:
|
||||
int first[12];
|
||||
int second[12];
|
||||
};
|
||||
|
||||
bool is_value_initialized(const private_int_array_pair& arg)
|
||||
{
|
||||
for ( unsigned i = 0; i < 12; ++i)
|
||||
{
|
||||
if ( (arg.first[i] != 0) || (arg.second[i] != 0) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_value_initialized(const T(& arg)[2])
|
||||
{
|
||||
return
|
||||
is_value_initialized(arg[0]) &&
|
||||
is_value_initialized(arg[1]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_value_initialized(const boost::value_initialized<T>& arg)
|
||||
{
|
||||
return is_value_initialized(arg.data());
|
||||
}
|
||||
|
||||
// Returns zero when the specified object is value-initializated, and one otherwise.
|
||||
// Prints a message to standard output if the value-initialization has failed.
|
||||
template <class T>
|
||||
unsigned failed_to_value_initialized(const T& object, const char *const object_name)
|
||||
{
|
||||
if ( is_value_initialized(object) )
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
|
||||
return 1u;
|
||||
}
|
||||
}
|
||||
|
||||
// A macro that passed both the name and the value of the specified object to
|
||||
// the function above here.
|
||||
#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
|
||||
|
||||
// Equivalent to the dirty_stack() function from GCC Bug 33916,
|
||||
// "Default constructor fails to initialize array members", reported in 2007 by
|
||||
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
|
||||
void dirty_stack()
|
||||
{
|
||||
unsigned char array_on_stack[4096];
|
||||
for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
|
||||
{
|
||||
array_on_stack[i] = 0x11;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
dirty_stack();
|
||||
|
||||
// TODO More types may be added later.
|
||||
const unsigned num_failures =
|
||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
|
||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
|
||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>());
|
||||
|
||||
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
// One or more failures are expected.
|
||||
return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
#else
|
||||
// No failures are expected.
|
||||
return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
#endif
|
||||
}
|
Reference in New Issue
Block a user