forked from boostorg/utility
Compare commits
20 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
6032348b4c | ||
|
3279399fe3 | ||
|
87875cadda | ||
|
c58748cfd9 | ||
|
58bb88d4bd | ||
|
11d50ecb9f | ||
|
636283d7c2 | ||
|
1df0bf80bc | ||
|
71e78a0081 | ||
|
f7e4b0e399 | ||
|
fb1d2effef | ||
|
94b91e8c92 | ||
|
a4b8043e68 | ||
|
b4a08fc80e | ||
|
9da96d9737 | ||
|
a991936c96 | ||
|
6239e685a2 | ||
|
e601fcb9c9 | ||
|
f29a5db08e | ||
|
22743ee125 |
74
assert.html
74
assert.html
@@ -17,36 +17,89 @@
|
|||||||
<td colspan="2" height="64"> </td>
|
<td colspan="2" height="64"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</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>
|
<p>
|
||||||
The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT</b>,
|
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>.
|
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>.
|
||||||
The macro is intended to be used in Boost libraries.
|
The macro is intended to be used in both Boost libraries and user
|
||||||
|
code.
|
||||||
</p>
|
</p>
|
||||||
<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P>
|
<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P>
|
||||||
<P>When the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
<P>If 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
|
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
|
allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without
|
||||||
affecting the definition of the standard <STRONG>assert</STRONG>.</P>
|
affecting the definition of the standard <STRONG>assert</STRONG>.</P>
|
||||||
<P>When the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
<P>If 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
|
is included, <tt>BOOST_ASSERT(expr)</tt> evaluates <b>expr</b> and, if the
|
||||||
result is false, evaluates the expression</P>
|
result is false, evaluates the expression</P>
|
||||||
|
<blockquote>
|
||||||
<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
||||||
__FILE__, __LINE__)</tt></P>
|
__FILE__, __LINE__)</tt></P>
|
||||||
|
</blockquote>
|
||||||
<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
||||||
as</P>
|
as</P>
|
||||||
<pre>
|
<blockquote>
|
||||||
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>
|
</pre>
|
||||||
|
</blockquote>
|
||||||
<p>but it is never defined. The user is expected to supply an appropriate
|
<p>but it is never defined. The user is expected to supply an appropriate
|
||||||
definition.</p>
|
definition.</p>
|
||||||
<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG>
|
<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>
|
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG>
|
||||||
will be redefined each time as specified above.</P>
|
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>.
|
<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
|
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
|
the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always
|
||||||
@@ -54,8 +107,9 @@ void assertion_failed(char const * expr, char const * function, char const * fil
|
|||||||
effects; it can also help suppress warnings about unused variables when the
|
effects; it can also help suppress warnings about unused variables when the
|
||||||
only use of the variable is inside an assertion.</p>
|
only use of the variable is inside an assertion.</p>
|
||||||
<p><br>
|
<p><br>
|
||||||
<small>Copyright <20> 2002, 2007 by Peter Dimov. Distributed under the Boost Software
|
<small>Copyright <20> 2002, 2007 by Peter Dimov. Copyright <20> 2011
|
||||||
|
by Beman Dawes. Distributed under the Boost Software
|
||||||
License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
|
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>
|
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>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -2,6 +2,7 @@
|
|||||||
// assert_test.cpp - a test for boost/assert.hpp
|
// assert_test.cpp - a test for boost/assert.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||||
|
// Copyright (2) Beman Dawes 2011
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -20,6 +21,11 @@ void test_default()
|
|||||||
BOOST_ASSERT(x);
|
BOOST_ASSERT(x);
|
||||||
BOOST_ASSERT(x == 1);
|
BOOST_ASSERT(x == 1);
|
||||||
BOOST_ASSERT(&x);
|
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
|
#define BOOST_DISABLE_ASSERTS
|
||||||
@@ -34,13 +40,23 @@ void test_disabled()
|
|||||||
BOOST_ASSERT(x == 1);
|
BOOST_ASSERT(x == 1);
|
||||||
BOOST_ASSERT(&x);
|
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(0);
|
||||||
BOOST_ASSERT(!x);
|
BOOST_ASSERT(!x);
|
||||||
BOOST_ASSERT(x == 0);
|
BOOST_ASSERT(x == 0);
|
||||||
|
|
||||||
|
BOOST_ASSERT_MSG(0, "msg");
|
||||||
|
BOOST_ASSERT_MSG(!x, "msg");
|
||||||
|
BOOST_ASSERT_MSG(x == 0, "msg");
|
||||||
|
|
||||||
void * p = 0;
|
void * p = 0;
|
||||||
|
|
||||||
BOOST_ASSERT(p);
|
BOOST_ASSERT(p);
|
||||||
|
BOOST_ASSERT_MSG(p, "msg");
|
||||||
|
|
||||||
// supress warnings
|
// supress warnings
|
||||||
p = &x;
|
p = &x;
|
||||||
@@ -55,6 +71,7 @@ void test_disabled()
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
int handler_invoked = 0;
|
int handler_invoked = 0;
|
||||||
|
int msg_handler_invoked = 0;
|
||||||
|
|
||||||
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
||||||
{
|
{
|
||||||
@@ -66,11 +83,24 @@ void boost::assertion_failed(char const * expr, char const * function, char cons
|
|||||||
++handler_invoked;
|
++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
|
struct X
|
||||||
{
|
{
|
||||||
static void f()
|
static void f()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(0);
|
BOOST_ASSERT(0);
|
||||||
|
BOOST_ASSERT_MSG(0, "msg f()");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,21 +113,35 @@ void test_handler()
|
|||||||
BOOST_ASSERT(x == 1);
|
BOOST_ASSERT(x == 1);
|
||||||
BOOST_ASSERT(&x);
|
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(0);
|
||||||
BOOST_ASSERT(!x);
|
BOOST_ASSERT(!x);
|
||||||
BOOST_ASSERT(x == 0);
|
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;
|
void * p = 0;
|
||||||
|
|
||||||
BOOST_ASSERT(p);
|
BOOST_ASSERT(p);
|
||||||
|
BOOST_ASSERT_MSG(p, "msg p");
|
||||||
|
|
||||||
X::f();
|
X::f();
|
||||||
|
|
||||||
BOOST_ASSERT(handler_invoked == 5);
|
BOOST_ASSERT(handler_invoked == 5);
|
||||||
BOOST_TEST(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_HANDLER
|
||||||
|
#undef BOOST_ENABLE_ASSERT_MSG_HANDLER
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
68
doc/Jamfile.v2
Normal file
68
doc/Jamfile.v2
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
# 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
Normal file
104
doc/declval.qbk
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
[/
|
||||||
|
/ 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]
|
||||||
|
|
||||||
|
|
||||||
|
|
163
doc/html/declval.html
Normal file
163
doc/html/declval.html
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<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>
|
@@ -1,8 +1,11 @@
|
|||||||
//
|
//
|
||||||
// boost/assert.hpp - BOOST_ASSERT(expr)
|
// 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) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||||
// Copyright (c) 2007 Peter Dimov
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
// Copyright (c) Beman Dawes 2011
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -13,6 +16,16 @@
|
|||||||
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
// 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
|
#undef BOOST_ASSERT
|
||||||
|
|
||||||
#if defined(BOOST_DISABLE_ASSERTS)
|
#if defined(BOOST_DISABLE_ASSERTS)
|
||||||
@@ -25,18 +38,86 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
void assertion_failed(char const * expr,
|
||||||
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
char const * function, char const * file, long line); // user defined
|
||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#else
|
||||||
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
|
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
|
||||||
# define BOOST_ASSERT(expr) assert(expr)
|
# define BOOST_ASSERT(expr) assert(expr)
|
||||||
#endif
|
#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
|
#undef BOOST_VERIFY
|
||||||
|
|
||||||
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
|
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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)
|
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||||
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||||
// for T::operator<, etc. (Daniel Frey)
|
// for T::operator<, etc. (Daniel Frey)
|
||||||
@@ -88,7 +90,7 @@
|
|||||||
# pragma set woff 1234
|
# pragma set woff 1234
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||||
#endif // operator-> not begin a UDT
|
#endif // operator-> not begin a UDT
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/lib/optional for documentation.
|
// See http://www.boost.org/libs/optional for documentation.
|
||||||
//
|
//
|
||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
44
include/boost/utility/declval.hpp
Normal file
44
include/boost/utility/declval.hpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// 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
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/lib/optional for documentation.
|
// See http://www.boost.org/libs/optional for documentation.
|
||||||
//
|
//
|
||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/lib/optional for documentation.
|
// See http://www.boost.org/libs/optional for documentation.
|
||||||
//
|
//
|
||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -35,10 +35,7 @@ struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||||
|
|
||||||
// As of N2588, C++0x result_of only supports function call
|
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
|
||||||
// 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())
|
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
@@ -56,18 +53,15 @@ struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
|||||||
|
|
||||||
namespace detail {
|
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())
|
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
class cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
{
|
{
|
||||||
static F f;
|
typedef decltype(
|
||||||
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
|
boost::declval<F>()(
|
||||||
public:
|
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<T, >() BOOST_PP_INTERCEPT)
|
||||||
typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type;
|
)
|
||||||
|
) type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/lib/optional for documentation.
|
// See http://www.boost.org/libs/optional for documentation.
|
||||||
//
|
//
|
||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -13,7 +13,9 @@
|
|||||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||||
#include <boost/preprocessor/repetition/enum_params.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/repetition/enum_shifted_params.hpp>
|
||||||
|
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/mpl/has_xxx.hpp>
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
@@ -22,6 +24,7 @@
|
|||||||
#include <boost/type_traits/is_pointer.hpp>
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
#include <boost/utility/declval.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/lib/optional for documentation.
|
// See http://www.boost.org/libs/optional for documentation.
|
||||||
//
|
//
|
||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
||||||
// 21 Ago 2008 (Added swap) 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
|
// 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
|
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
@@ -20,6 +22,7 @@
|
|||||||
// contains. More details on these issues are at libs/utility/value_init.htm
|
// contains. More details on these issues are at libs/utility/value_init.htm
|
||||||
|
|
||||||
#include <boost/aligned_storage.hpp>
|
#include <boost/aligned_storage.hpp>
|
||||||
|
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/type_traits/cv_traits.hpp>
|
#include <boost/type_traits/cv_traits.hpp>
|
||||||
@@ -28,10 +31,39 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <new>
|
#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 {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class value_initialized
|
class initialized
|
||||||
{
|
{
|
||||||
private :
|
private :
|
||||||
struct wrapper
|
struct wrapper
|
||||||
@@ -40,6 +72,18 @@ class value_initialized
|
|||||||
typename
|
typename
|
||||||
#endif
|
#endif
|
||||||
remove_const<T>::type data;
|
remove_const<T>::type data;
|
||||||
|
|
||||||
|
wrapper()
|
||||||
|
:
|
||||||
|
data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper(T const & arg)
|
||||||
|
:
|
||||||
|
data(arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable
|
mutable
|
||||||
@@ -55,30 +99,25 @@ class value_initialized
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
value_initialized()
|
initialized()
|
||||||
{
|
{
|
||||||
|
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||||
std::memset(&x, 0, sizeof(x));
|
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
|
#endif
|
||||||
new (wrapper_address()) wrapper();
|
new (wrapper_address()) wrapper();
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_initialized(value_initialized const & arg)
|
initialized(initialized const & arg)
|
||||||
{
|
{
|
||||||
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
||||||
}
|
}
|
||||||
|
|
||||||
value_initialized & operator=(value_initialized const & arg)
|
explicit initialized(T const & arg)
|
||||||
|
{
|
||||||
|
new (wrapper_address()) wrapper(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized & operator=(initialized const & arg)
|
||||||
{
|
{
|
||||||
// Assignment is only allowed when T is non-const.
|
// Assignment is only allowed when T is non-const.
|
||||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||||
@@ -86,7 +125,7 @@ class value_initialized
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~value_initialized()
|
~initialized()
|
||||||
{
|
{
|
||||||
wrapper_address()->wrapper::~wrapper();
|
wrapper_address()->wrapper::~wrapper();
|
||||||
}
|
}
|
||||||
@@ -101,17 +140,81 @@ class value_initialized
|
|||||||
return wrapper_address()->data;
|
return wrapper_address()->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(value_initialized & arg)
|
void swap(initialized & arg)
|
||||||
{
|
{
|
||||||
::boost::swap( this->data(), arg.data() );
|
::boost::swap( this->data(), arg.data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T const &() const { return this->data(); }
|
operator T const &() const
|
||||||
|
{
|
||||||
|
return wrapper_address()->data;
|
||||||
|
}
|
||||||
|
|
||||||
operator T&() { return this->data(); }
|
operator T&()
|
||||||
|
{
|
||||||
|
return wrapper_address()->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>
|
template<class T>
|
||||||
@@ -119,6 +222,7 @@ T const& get ( value_initialized<T> const& x )
|
|||||||
{
|
{
|
||||||
return x.data() ;
|
return x.data() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T& get ( value_initialized<T>& x )
|
T& get ( value_initialized<T>& x )
|
||||||
{
|
{
|
||||||
@@ -138,7 +242,7 @@ class initialized_value_t
|
|||||||
|
|
||||||
template <class T> operator T() const
|
template <class T> operator T() const
|
||||||
{
|
{
|
||||||
return get( value_initialized<T>() );
|
return initialized<T>().data();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -147,5 +251,8 @@ initialized_value_t const initialized_value = {} ;
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
12
index.html
12
index.html
@@ -14,20 +14,28 @@
|
|||||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>
|
<p>
|
||||||
|
<a href="utility.htm#addressof">addressof</a><br>
|
||||||
<a href="assert.html">assert</a><br>
|
<a href="assert.html">assert</a><br>
|
||||||
<a href="base_from_member.html">base_from_member</a><br>
|
<a href="base_from_member.html">base_from_member</a><br>
|
||||||
|
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
|
||||||
<a href="call_traits.htm">call_traits</a><br>
|
<a href="call_traits.htm">call_traits</a><br>
|
||||||
<a href="checked_delete.html">checked_delete</a><br>
|
<a href="checked_delete.html">checked_delete</a><br>
|
||||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||||
<a href="current_function.html">current_function</a><br>
|
<a href="current_function.html">current_function</a><br>
|
||||||
<a href="enable_if.html">enable_if</a><br>
|
<a href="doc/html/declval.html">declval</a><br>
|
||||||
|
<a href="enable_if.html">enable_if</a><br>
|
||||||
|
<a href="in_place_factories.html">in_place_factory</a><br>
|
||||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||||
|
<a href="utility.htm#functions_next_prior">next/prior</a><br>
|
||||||
|
<a href="utility.htm#Class_noncopyable">noncopyable</a><br>
|
||||||
<a href="operators.htm">operators</a><br>
|
<a href="operators.htm">operators</a><br>
|
||||||
|
<a href="utility.htm#result_of">result_of</a><br>
|
||||||
<a href="swap.html">swap</a><br>
|
<a href="swap.html">swap</a><br>
|
||||||
<a href="throw_exception.html">throw_exception</a><br>
|
<a href="throw_exception.html">throw_exception</a><br>
|
||||||
<a href="utility.htm">utility</a><br>
|
<a href="utility.htm">utility</a><br>
|
||||||
<a href="value_init.htm">value_init</a></p>
|
<a href="value_init.htm">value_init</a>
|
||||||
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<hr>
|
<hr>
|
||||||
<p>© Copyright Beman Dawes, 2001</p>
|
<p>© Copyright Beman Dawes, 2001</p>
|
||||||
|
116
initialized_test.cpp
Normal file
116
initialized_test.cpp
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// 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();
|
||||||
|
}
|
33
initialized_test_fail1.cpp
Normal file
33
initialized_test_fail1.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
37
initialized_test_fail2.cpp
Normal file
37
initialized_test_fail2.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
@@ -32,9 +32,13 @@ test-suite utility
|
|||||||
[ compile result_of_test.cpp ]
|
[ compile result_of_test.cpp ]
|
||||||
[ run ../shared_iterator_test.cpp ]
|
[ run ../shared_iterator_test.cpp ]
|
||||||
[ run ../value_init_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_fail1.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||||
[ run ../verify_test.cpp ]
|
[ run ../verify_test.cpp ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
0
test/next_prior_test.cpp
Executable file → Normal file
0
test/next_prior_test.cpp
Executable file → Normal file
@@ -98,6 +98,11 @@ struct no_result_type_or_result_of
|
|||||||
unsigned int operator()();
|
unsigned int operator()();
|
||||||
unsigned short operator()() volatile;
|
unsigned short operator()() volatile;
|
||||||
const unsigned short operator()() const 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>
|
template<typename T>
|
||||||
@@ -108,6 +113,11 @@ struct no_result_type_or_result_of_template
|
|||||||
unsigned int operator()();
|
unsigned int operator()();
|
||||||
unsigned short operator()() volatile;
|
unsigned short operator()() volatile;
|
||||||
const unsigned short operator()() const 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 {};
|
struct X {};
|
||||||
@@ -232,6 +242,14 @@ 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<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<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));
|
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
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
98
utility.htm
98
utility.htm
@@ -151,37 +151,95 @@ void f() {
|
|||||||
<code>result_of<F(T1, T2, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)>::type</code> defines the result type
|
T<em>N</em>)>::type</code> defines the result type
|
||||||
of the expression <code>f(t1, t2,
|
of the expression <code>f(t1, t2,
|
||||||
...,t<em>N</em>)</code>. The implementation permits
|
...,t<em>N</em>)</code>. This implementation permits
|
||||||
the type <code>F</code> to be a function pointer,
|
the type <code>F</code> to be a function pointer,
|
||||||
function reference, member function pointer, or class
|
function reference, member function pointer, or class
|
||||||
type.</p> <p>If your compiler does not support
|
type. By default, <em>N</em> may be any value between 0 and
|
||||||
<code>decltype</code>, then when <code>F</code> is a
|
10. To change the upper limit, define the macro
|
||||||
class type with a member type <code>result_type</code>,
|
<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>,
|
||||||
<code>result_of<F(T1, T2, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)></code> is
|
T<em>N</em>)></code> is
|
||||||
<code>F::result_type</code>. When <code>F</code>
|
<code>F::result_type</code>. When <code>F</code> does
|
||||||
does not contain <code>result_type</code>,
|
not contain <code>result_type</code>,
|
||||||
<code>result_of<F(T1, T2, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||||
T2, ..., T<em>N</em>)>::type</code> when
|
T2, ..., T<em>N</em>)>::type</code> when
|
||||||
<code><em>N</em> > 0</code> or <code>void</code>
|
<code><em>N</em> > 0</code> or <code>void</code>
|
||||||
when <code><em>N</em> = 0</code>. For additional
|
when <code><em>N</em> = 0</code>. Note that it is the
|
||||||
information about <code>result_of</code>, see the
|
responsibility of the programmer to ensure that
|
||||||
C++ Library Technical Report, <a
|
function objects accurately advertise their result
|
||||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
type via this protocol, as in the following
|
||||||
or, for motivation and design rationale, the <code>result_of</code> <a
|
example.</p>
|
||||||
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
|
||||||
|
|
||||||
<p>Class template <code>result_of</code> resides in
|
<blockquote>
|
||||||
the header <code><<a
|
<pre>struct functor {
|
||||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
|
template<class> struct result;
|
||||||
default, <em>N</em> may be any value between 0 and
|
|
||||||
10. To change the upper limit, define the macro
|
template<class F, class T>
|
||||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
struct result<F(T)> {
|
||||||
value for <em>N</em>.</p>
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T operator()(T x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::result_of<
|
||||||
|
functor(int)
|
||||||
|
>::type type;</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<a name="BOOST_NO_RESULT_OF"></a>
|
<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>. 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>.</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>
|
||||||
|
|
||||||
<h2>Class templates for the Base-from-Member Idiom</h2>
|
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||||
|
140
value_init.htm
140
value_init.htm
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
<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>
|
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@@ -123,6 +124,12 @@ constructed by the following declaration:
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
<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>
|
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||||
allows value-initializing a variable as follows:
|
allows value-initializing a variable as follows:
|
||||||
<pre>
|
<pre>
|
||||||
@@ -216,37 +223,65 @@ 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
|
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,
|
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.
|
and the type of object you would like to have value-initialized.
|
||||||
Compilers usually support value-initialization for built-in types properly.
|
All compilers we have tested so far support value-initialization for arithmetic types properly.
|
||||||
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
|
However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
|
||||||
be partially, or even entirely left uninitialized, when they should be value-initialized.
|
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
|
||||||
|
go wrong on various compilers.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
We have encountered issues regarding value-initialization on compilers by
|
At the moment of writing, May 2010, the following reported issues regarding
|
||||||
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
|
value-initialization are still there in current compiler releases:
|
||||||
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
|
<ul>
|
||||||
<tr><td>
|
<li>
|
||||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
|
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
|
||||||
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
|
Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
|
||||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
|
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
|
<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
|
||||||
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
|
Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
|
||||||
<br>Reported by Jonathan Wakely, 2006-12-07
|
<br>Reported by Sylvester Hesp, 2009
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
|
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
|
||||||
GCC Bug 33916 - Default constructor fails to initialize array members</a>
|
Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
|
||||||
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
|
<br>Reported by Alex Vakulenko, 2009
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
|
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
|
||||||
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
|
Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
|
||||||
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
|
<br>Reported by Niels Dekker (LKEB), 2010
|
||||||
<br>
|
</li><li>
|
||||||
</td></tr></table>
|
<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.
|
||||||
</p><p>
|
</p><p>
|
||||||
|
|
||||||
New versions of <code>value_initialized</code>
|
New versions of <code>value_initialized</code>
|
||||||
(Boost release version 1.35 or higher)
|
(Boost release version 1.35 or higher)
|
||||||
offer a workaround to these issues: <code>value_initialized</code> will now clear
|
offer a workaround to these issues: <code>value_initialized</code> may now clear
|
||||||
its internal data, prior to constructing the object that it contains.
|
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.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2><a name="types"></a>Types and objects</h2>
|
<h2><a name="types"></a>Types and objects</h2>
|
||||||
@@ -340,6 +375,52 @@ 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>
|
<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>
|
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@@ -399,6 +480,9 @@ Special thanks to Björn Karlsson who carefully edited and completed this do
|
|||||||
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
<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.
|
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||||
</p>
|
</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>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||||
</p>
|
</p>
|
||||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
||||||
@@ -407,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised 03 October 2009</p>
|
<p>Revised 30 May 2010</p>
|
||||||
|
|
||||||
<p>© Copyright Fernando Cacciola, 2002, 2009.</p>
|
<p>© Copyright Fernando Cacciola, 2002 - 2010.</p>
|
||||||
|
|
||||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
<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>
|
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boost/test/minimal.hpp"
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sample POD type
|
// Sample POD type
|
||||||
@@ -215,7 +215,7 @@ template<class T>
|
|||||||
void check_initialized_value ( T const& y )
|
void check_initialized_value ( T const& y )
|
||||||
{
|
{
|
||||||
T initializedValue = boost::initialized_value ;
|
T initializedValue = boost::initialized_value ;
|
||||||
BOOST_CHECK ( y == initializedValue ) ;
|
BOOST_TEST ( y == initializedValue ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
@@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& )
|
|||||||
template<class T>
|
template<class T>
|
||||||
bool test ( T const& y, T const& z )
|
bool test ( T const& y, T const& z )
|
||||||
{
|
{
|
||||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
const int errors_before_test = boost::detail::test_errors();
|
||||||
|
|
||||||
check_initialized_value(y);
|
check_initialized_value(y);
|
||||||
|
|
||||||
boost::value_initialized<T> x ;
|
boost::value_initialized<T> x ;
|
||||||
BOOST_CHECK ( y == x ) ;
|
BOOST_TEST ( y == x ) ;
|
||||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
BOOST_TEST ( y == boost::get(x) ) ;
|
||||||
|
|
||||||
static_cast<T&>(x) = z ;
|
static_cast<T&>(x) = z ;
|
||||||
boost::get(x) = z ;
|
boost::get(x) = z ;
|
||||||
BOOST_CHECK ( x == z ) ;
|
BOOST_TEST ( x == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const x_c ;
|
boost::value_initialized<T> const x_c ;
|
||||||
BOOST_CHECK ( y == x_c ) ;
|
BOOST_TEST ( y == x_c ) ;
|
||||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
BOOST_TEST ( y == boost::get(x_c) ) ;
|
||||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||||
x_c_ref = z ;
|
x_c_ref = z ;
|
||||||
BOOST_CHECK ( x_c == z ) ;
|
BOOST_TEST ( x_c == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const copy1 = x;
|
boost::value_initialized<T> const copy1 = x;
|
||||||
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> copy2;
|
boost::value_initialized<T> copy2;
|
||||||
copy2 = x;
|
copy2 = x;
|
||||||
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||||
BOOST_CHECK ( y == *ptr ) ;
|
BOOST_TEST ( y == *ptr ) ;
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
boost::value_initialized<T const> cx ;
|
boost::value_initialized<T const> cx ;
|
||||||
BOOST_CHECK ( y == cx ) ;
|
BOOST_TEST ( y == cx ) ;
|
||||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
BOOST_TEST ( y == boost::get(cx) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T const> const cx_c ;
|
boost::value_initialized<T const> const cx_c ;
|
||||||
BOOST_CHECK ( y == cx_c ) ;
|
BOOST_TEST ( y == cx_c ) ;
|
||||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
return boost::detail::test_errors() == errors_before_test ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_main(int, char **)
|
int main(int, char **)
|
||||||
{
|
{
|
||||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
||||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||||
|
|
||||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||||
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||||
|
|
||||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||||
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||||
|
|
||||||
StringAndInt stringAndInt0;
|
StringAndInt stringAndInt0;
|
||||||
StringAndInt stringAndInt1;
|
StringAndInt stringAndInt1;
|
||||||
stringAndInt0.i = 0;
|
stringAndInt0.i = 0;
|
||||||
stringAndInt1.i = 1;
|
stringAndInt1.i = 1;
|
||||||
stringAndInt1.s = std::string("1");
|
stringAndInt1.s = std::string("1");
|
||||||
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
||||||
|
|
||||||
StructWithDestructor structWithDestructor0;
|
StructWithDestructor structWithDestructor0;
|
||||||
StructWithDestructor structWithDestructor1;
|
StructWithDestructor structWithDestructor1;
|
||||||
structWithDestructor0.i = 0;
|
structWithDestructor0.i = 0;
|
||||||
structWithDestructor1.i = 1;
|
structWithDestructor1.i = 1;
|
||||||
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
||||||
|
|
||||||
StructWithVirtualFunction structWithVirtualFunction0;
|
StructWithVirtualFunction structWithVirtualFunction0;
|
||||||
StructWithVirtualFunction structWithVirtualFunction1;
|
StructWithVirtualFunction structWithVirtualFunction1;
|
||||||
structWithVirtualFunction0.i = 0;
|
structWithVirtualFunction0.i = 0;
|
||||||
structWithVirtualFunction1.i = 1;
|
structWithVirtualFunction1.i = 1;
|
||||||
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||||
|
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||||
|
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||||
|
|
||||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||||
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||||
get(swapFunctionCallTester1).data = 1;
|
get(swapFunctionCallTester1).data = 1;
|
||||||
get(swapFunctionCallTester2).data = 2;
|
get(swapFunctionCallTester2).data = 2;
|
||||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||||
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||||
|
|
||||||
return 0;
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
144
value_init_workaround_test.cpp
Normal file
144
value_init_workaround_test.cpp
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
// 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