forked from boostorg/utility
Compare commits
67 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 | |||
e3c982287a | |||
82e1111bb8 | |||
9339b32178 | |||
3770221507 | |||
e6cb3a77ee | |||
bbccfbbab4 | |||
74a6a693d3 | |||
bf713ad47a | |||
76b17c497b | |||
3de5974419 | |||
7eb1536590 | |||
9339431e03 | |||
f2349baf7d | |||
8745ca628a | |||
ba61e9d796 | |||
afe74fffbc | |||
09a0137016 | |||
a1d3ec6c53 | |||
5be3004e6c | |||
d387905150 | |||
b514e40733 | |||
b02677375f | |||
61a6015b5a | |||
682032a340 | |||
67afd7e315 | |||
75cf20cace | |||
91385ac627 | |||
61e9b93f7c | |||
d97b303777 | |||
3900e8ece4 | |||
e27fc4a853 | |||
f7aa9a8935 | |||
0af1959b30 | |||
5f0cf4f5de | |||
0282c8a141 | |||
6725719bd9 | |||
97e11b024e | |||
118e473a3d | |||
d4b6193f94 | |||
d420c98a53 | |||
d153ab4daa | |||
561f83b991 | |||
57124703f9 | |||
53f6d10652 | |||
ebe853ff2f | |||
487a5c1ea5 | |||
c4338b1ce8 |
@ -85,7 +85,7 @@
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
@ -509,7 +509,7 @@ Returns the largest size that this Collection can ever have. <A href="#8">[8]</A
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
@ -160,7 +160,7 @@ t.~T()
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
@ -185,7 +185,7 @@
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
@ -70,7 +70,7 @@
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
76
addressof_fn_test.cpp
Normal file
76
addressof_fn_test.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
// addressof_fn_test.cpp: addressof( f )
|
||||
//
|
||||
// Copyright (c) 2008, 2009 Peter Dimov
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
|
||||
void f0()
|
||||
{
|
||||
}
|
||||
|
||||
void f1(int)
|
||||
{
|
||||
}
|
||||
|
||||
void f2(int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f3(int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f4(int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f5(int, int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f6(int, int, int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f7(int, int, int, int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f8(int, int, int, int, int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void f9(int, int, int, int, int, int, int, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( boost::addressof( f0 ) == &f0 );
|
||||
BOOST_TEST( boost::addressof( f1 ) == &f1 );
|
||||
BOOST_TEST( boost::addressof( f2 ) == &f2 );
|
||||
BOOST_TEST( boost::addressof( f3 ) == &f3 );
|
||||
BOOST_TEST( boost::addressof( f4 ) == &f4 );
|
||||
BOOST_TEST( boost::addressof( f5 ) == &f5 );
|
||||
BOOST_TEST( boost::addressof( f6 ) == &f6 );
|
||||
BOOST_TEST( boost::addressof( f7 ) == &f7 );
|
||||
BOOST_TEST( boost::addressof( f8 ) == &f8 );
|
||||
BOOST_TEST( boost::addressof( f9 ) == &f9 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
95
addressof_test2.cpp
Normal file
95
addressof_test2.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||
// Douglas Gregor (gregod@cs.rpi.edu)
|
||||
//
|
||||
// Copyright 2009 Peter Dimov
|
||||
//
|
||||
// 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)
|
||||
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
#include <boost/utility/addressof.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
template<class T> void scalar_test( T * = 0 )
|
||||
{
|
||||
T* px = new T();
|
||||
|
||||
T& x = *px;
|
||||
BOOST_TEST( boost::addressof(x) == px );
|
||||
|
||||
const T& cx = *px;
|
||||
const T* pcx = boost::addressof(cx);
|
||||
BOOST_TEST( pcx == px );
|
||||
|
||||
volatile T& vx = *px;
|
||||
volatile T* pvx = boost::addressof(vx);
|
||||
BOOST_TEST( pvx == px );
|
||||
|
||||
const volatile T& cvx = *px;
|
||||
const volatile T* pcvx = boost::addressof(cvx);
|
||||
BOOST_TEST( pcvx == px );
|
||||
|
||||
delete px;
|
||||
}
|
||||
|
||||
template<class T> void array_test( T * = 0 )
|
||||
{
|
||||
T nrg[3] = {1,2,3};
|
||||
T (*pnrg)[3] = &nrg;
|
||||
BOOST_TEST( boost::addressof(nrg) == pnrg );
|
||||
|
||||
T const cnrg[3] = {1,2,3};
|
||||
T const (*pcnrg)[3] = &cnrg;
|
||||
BOOST_TEST( boost::addressof(cnrg) == pcnrg );
|
||||
}
|
||||
|
||||
class convertible {
|
||||
public:
|
||||
|
||||
convertible( int = 0 )
|
||||
{
|
||||
}
|
||||
|
||||
template<class U> operator U () const
|
||||
{
|
||||
return U();
|
||||
}
|
||||
};
|
||||
|
||||
class convertible2 {
|
||||
public:
|
||||
|
||||
convertible2( int = 0 )
|
||||
{
|
||||
}
|
||||
|
||||
operator convertible2* () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
scalar_test<convertible>();
|
||||
scalar_test<convertible2>();
|
||||
|
||||
array_test<convertible>();
|
||||
array_test<convertible2>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
74
assert.html
74
assert.html
@ -17,36 +17,89 @@
|
||||
<td colspan="2" height="64"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
<a href="#BOOST_ASSERT">BOOST_ASSERT</a><br>
|
||||
<a href="#BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a><br>
|
||||
<a href="#BOOST_VERIFY">BOOST_VERIFY</a></p>
|
||||
|
||||
<h2><a name="BOOST_ASSERT">BOOST_ASSERT</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT</b>,
|
||||
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>.
|
||||
The macro is intended to be used in Boost libraries.
|
||||
The macro is intended to be used in both Boost libraries and user
|
||||
code.
|
||||
</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
|
||||
allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without
|
||||
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
|
||||
result is false, evaluates the expression</P>
|
||||
<blockquote>
|
||||
<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
||||
__FILE__, __LINE__)</tt></P>
|
||||
</blockquote>
|
||||
<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
||||
as</P>
|
||||
<pre>
|
||||
namespace boost
|
||||
<blockquote>
|
||||
<pre>namespace boost
|
||||
{
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line);
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>but it is never defined. The user is expected to supply an appropriate
|
||||
definition.</p>
|
||||
<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG>
|
||||
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG>
|
||||
will be redefined each time as specified above.</P>
|
||||
|
||||
<h2><a name="BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT_MSG</b>,
|
||||
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>,
|
||||
but with an additional macro parameter supplying an error message. The macro is intended to be used in both Boost libraries
|
||||
and user code.
|
||||
</p>
|
||||
<P> <tt>BOOST_ASSERT_MSG(expr, msg)</tt> is equivalent to <code>
|
||||
((void)0)</code> if <b>BOOST_DISABLE_ASSERTS</b> or <b>NDEBUG</b> are
|
||||
defined or <code>expr</code> evaluates to <code>true</code>. If those
|
||||
macros and <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> are not
|
||||
defined, and <code>expr</code> evaluates to <code>false</code>, an error
|
||||
message that includes <tt>#expr</tt>, <tt>msg</tt>, <tt> <a href="current_function.html">BOOST_CURRENT_FUNCTION</a></tt>, <tt>
|
||||
__FILE__</tt>, and <tt>__LINE__</tt> is sent to output stream <b>
|
||||
BOOST_ASSERT_MSG_OSTREAM</b>
|
||||
and <code>std::abort()</code> is called.</P>
|
||||
<P> <b>BOOST_ASSERT_MSG_OSTREAM</b> defines the output stream. It defaults to <code>std::cerr</code>.
|
||||
Integrated development environments (IDE's) like Microsoft Visual Studio
|
||||
may produce easier to understand output if messages go to a different
|
||||
stream, such as <code>std::cout</code>. Users may define <b>BOOST_ASSERT_MSG_OSTREAM</b> before including <STRONG><boost/assert.hpp></STRONG>
|
||||
to specify a different output stream. </P>
|
||||
<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG>
|
||||
is included, instead of sending a error message to an output
|
||||
stream, this expression is evaluated</P>
|
||||
<blockquote>
|
||||
<P><tt>::boost::assertion_failed_msg(#expr, msg, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
|
||||
__FILE__, __LINE__)</tt></P>
|
||||
</blockquote>
|
||||
<P><STRONG>assertion_failed_msg</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG>
|
||||
as</P>
|
||||
<blockquote>
|
||||
<pre>namespace boost
|
||||
{
|
||||
void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>but it is never defined. The user is expected to supply an appropriate
|
||||
definition.</p>
|
||||
<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG>
|
||||
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT_MSG</STRONG>
|
||||
will be redefined each time as specified above.</P>
|
||||
|
||||
<h2><a name="BOOST_VERIFY">BOOST_VERIFY</a></h2>
|
||||
<p><STRONG><boost/assert.hpp></STRONG> also defines the macro <STRONG>BOOST_VERIFY</STRONG>.
|
||||
It has exactly the same behavior as <STRONG>BOOST_ASSERT</STRONG>, except that
|
||||
the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always
|
||||
@ -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
|
||||
only use of the variable is inside an assertion.</p>
|
||||
<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>
|
||||
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -2,6 +2,7 @@
|
||||
// assert_test.cpp - a test for boost/assert.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (2) Beman Dawes 2011
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -20,6 +21,11 @@ void test_default()
|
||||
BOOST_ASSERT(x);
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg");
|
||||
BOOST_ASSERT_MSG(x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg");
|
||||
BOOST_ASSERT_MSG(&x, "msg");
|
||||
}
|
||||
|
||||
#define BOOST_DISABLE_ASSERTS
|
||||
@ -34,13 +40,23 @@ void test_disabled()
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg");
|
||||
BOOST_ASSERT_MSG(x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg");
|
||||
BOOST_ASSERT_MSG(&x, "msg");
|
||||
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT(!x);
|
||||
BOOST_ASSERT(x == 0);
|
||||
|
||||
BOOST_ASSERT_MSG(0, "msg");
|
||||
BOOST_ASSERT_MSG(!x, "msg");
|
||||
BOOST_ASSERT_MSG(x == 0, "msg");
|
||||
|
||||
void * p = 0;
|
||||
|
||||
BOOST_ASSERT(p);
|
||||
BOOST_ASSERT_MSG(p, "msg");
|
||||
|
||||
// supress warnings
|
||||
p = &x;
|
||||
@ -55,6 +71,7 @@ void test_disabled()
|
||||
#include <cstdio>
|
||||
|
||||
int handler_invoked = 0;
|
||||
int msg_handler_invoked = 0;
|
||||
|
||||
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
||||
{
|
||||
@ -66,11 +83,24 @@ void boost::assertion_failed(char const * expr, char const * function, char cons
|
||||
++handler_invoked;
|
||||
}
|
||||
|
||||
void boost::assertion_failed_msg(char const * expr, char const * msg, char const * function,
|
||||
char const * file, long line)
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::printf;
|
||||
#endif
|
||||
|
||||
printf("Expression: %s Message: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n",
|
||||
expr, msg, function, file, line);
|
||||
++msg_handler_invoked;
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
static void f()
|
||||
{
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT_MSG(0, "msg f()");
|
||||
}
|
||||
};
|
||||
|
||||
@ -83,21 +113,35 @@ void test_handler()
|
||||
BOOST_ASSERT(x == 1);
|
||||
BOOST_ASSERT(&x);
|
||||
|
||||
BOOST_ASSERT_MSG(1, "msg2");
|
||||
BOOST_ASSERT_MSG(x, "msg3");
|
||||
BOOST_ASSERT_MSG(x == 1, "msg4");
|
||||
BOOST_ASSERT_MSG(&x, "msg5");
|
||||
|
||||
BOOST_ASSERT(0);
|
||||
BOOST_ASSERT(!x);
|
||||
BOOST_ASSERT(x == 0);
|
||||
|
||||
BOOST_ASSERT_MSG(0,"msg 0");
|
||||
BOOST_ASSERT_MSG(!x, "msg !x");
|
||||
BOOST_ASSERT_MSG(x == 0, "msg x == 0");
|
||||
|
||||
void * p = 0;
|
||||
|
||||
BOOST_ASSERT(p);
|
||||
BOOST_ASSERT_MSG(p, "msg p");
|
||||
|
||||
X::f();
|
||||
|
||||
BOOST_ASSERT(handler_invoked == 5);
|
||||
BOOST_TEST(handler_invoked == 5);
|
||||
|
||||
BOOST_ASSERT_MSG(msg_handler_invoked == 5, "msg_handler_invoked count is wrong");
|
||||
BOOST_TEST(msg_handler_invoked == 5);
|
||||
}
|
||||
|
||||
#undef BOOST_ENABLE_ASSERT_HANDLER
|
||||
#undef BOOST_ENABLE_ASSERT_MSG_HANDLER
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -281,7 +281,7 @@ object_id_compare::operator ()
|
||||
}
|
||||
else
|
||||
{
|
||||
return a.second->before( *b.second );
|
||||
return a.second->before( *b.second ) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
|
||||
#endif
|
||||
|
||||
/*
|
||||
Note: This file tests every single valid bit-grouping on its own, and some
|
||||
random combinations of bit-groupings.
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include <libs/type_traits/test/test.hpp>
|
||||
#include <libs/type_traits/test/check_type.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
|
||||
#endif
|
||||
|
||||
// a way prevent warnings for unused variables
|
||||
template<class T> inline void unused_variable(const T&) {}
|
||||
|
||||
@ -52,7 +56,8 @@ struct contained
|
||||
const_reference const_get()const { return v_; }
|
||||
// pass value:
|
||||
void call(param_type){}
|
||||
|
||||
private:
|
||||
contained& operator=(const contained&);
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
@ -77,6 +82,8 @@ struct contained<T[N]>
|
||||
reference get() { return v_; }
|
||||
const_reference const_get()const { return v_; }
|
||||
void call(param_type){}
|
||||
private:
|
||||
contained& operator=(const contained&);
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -197,7 +204,7 @@ struct comparible_UDT
|
||||
bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[ ])
|
||||
int main()
|
||||
{
|
||||
call_traits_checker<comparible_UDT> c1;
|
||||
comparible_UDT u;
|
||||
|
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>
|
@ -146,7 +146,7 @@ int main()
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
|
@ -99,7 +99,7 @@ directly to the container:</p>
|
||||
<H2><A NAME="framework"></A>Framework</H2>
|
||||
<p>
|
||||
This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring
|
||||
the entire set of constructor overloads ftom the contained type. It also allows the container to remove the CopyConstuctible
|
||||
the entire set of constructor overloads from the contained type. It also allows the container to remove the CopyConstuctible
|
||||
requirement from the contained type since objects can be directly constructed in-place without need of a copy.<br>
|
||||
The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized).
|
||||
Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override
|
||||
@ -117,7 +117,7 @@ The following simplified example shows the basic idea. A complete example follow
|
||||
<pre>struct C
|
||||
{
|
||||
template<class InPlaceFactory>
|
||||
C ( InPlaceFactory const& aFactoty )
|
||||
C ( InPlaceFactory const& aFactory )
|
||||
:
|
||||
contained_ ( uninitialized_storage() )
|
||||
{
|
||||
@ -293,4 +293,4 @@ the latest version of this file can be found at <A
|
||||
HREF="http://www.boost.org">www.boost.org</A>, and the boost
|
||||
<A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
</HTML>
|
||||
|
@ -1,8 +1,11 @@
|
||||
//
|
||||
// boost/assert.hpp - BOOST_ASSERT(expr)
|
||||
// BOOST_ASSERT_MSG(expr, msg)
|
||||
// BOOST_VERIFY(expr)
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
// Copyright (c) Beman Dawes 2011
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -13,6 +16,16 @@
|
||||
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
||||
//
|
||||
|
||||
//
|
||||
// Stop inspect complaining about use of 'assert':
|
||||
//
|
||||
// boostinspect:naassert_macro
|
||||
//
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_ASSERT //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#undef BOOST_ASSERT
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS)
|
||||
@ -25,18 +38,86 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
||||
|
||||
void assertion_failed(char const * expr,
|
||||
char const * function, char const * file, long line); // user defined
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
#define BOOST_ASSERT(expr) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
|
||||
# define BOOST_ASSERT(expr) assert(expr)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_ASSERT_MSG //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
# undef BOOST_ASSERT_MSG
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((void)0)
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
void assertion_failed_msg(char const * expr, char const * msg,
|
||||
char const * function, char const * file, long line); // user defined
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
#ifndef BOOST_ASSERT_HPP
|
||||
#define BOOST_ASSERT_HPP
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
// IDE's like Visual Studio perform better if output goes to std::cout or
|
||||
// some other stream, so allow user to configure output stream:
|
||||
#ifndef BOOST_ASSERT_MSG_OSTREAM
|
||||
# define BOOST_ASSERT_MSG_OSTREAM std::cerr
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace assertion
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline void assertion_failed_msg(char const * expr, char const * msg, char const * function,
|
||||
char const * file, long line)
|
||||
{
|
||||
BOOST_ASSERT_MSG_OSTREAM
|
||||
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
||||
<< function << ":\n"
|
||||
<< file << '(' << line << "): " << msg << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
} // detail
|
||||
} // assertion
|
||||
} // detail
|
||||
#endif
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
|
||||
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// BOOST_VERIFY //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#undef BOOST_VERIFY
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
|
||||
|
@ -6,12 +6,6 @@
|
||||
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <boost/exception/error_info.hpp>
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
#include <boost/exception/info.hpp>
|
||||
#include <boost/exception/info_tuple.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#error The header <boost/exception.hpp> has been deprecated. Please #include <boost/exception/all.hpp> instead.
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,8 @@
|
||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||
|
||||
// Revision History
|
||||
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||
// (Matthew Bradbury, fixes #4432)
|
||||
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||
// for T::operator<, etc. (Daniel Frey)
|
||||
@ -88,7 +90,7 @@
|
||||
# pragma set woff 1234
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||
#endif // operator-> not begin a UDT
|
||||
|
||||
|
@ -179,6 +179,11 @@ unwrap_ref(T& t)
|
||||
return t;
|
||||
}
|
||||
|
||||
template<class T> inline T* get_pointer( reference_wrapper<T> const & r )
|
||||
{
|
||||
return r.get_pointer();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_REF_HPP_INCLUDED
|
||||
|
@ -7,6 +7,6 @@
|
||||
#ifndef BOOST_SWAP_HPP
|
||||
#define BOOST_SWAP_HPP
|
||||
|
||||
#include "./utility/swap.hpp"
|
||||
#include "boost/utility/swap.hpp"
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,17 @@ namespace boost
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct addr_impl_ref
|
||||
{
|
||||
T & v_;
|
||||
|
||||
inline addr_impl_ref( T & v ): v_( v ) {}
|
||||
inline operator T& () const { return v_; }
|
||||
|
||||
private:
|
||||
addr_impl_ref & operator=(const addr_impl_ref &);
|
||||
};
|
||||
|
||||
template<class T> struct addressof_impl
|
||||
{
|
||||
static inline T * f( T & v, long )
|
||||
@ -39,12 +50,40 @@ template<class T> struct addressof_impl
|
||||
|
||||
template<class T> T * addressof( T & v )
|
||||
{
|
||||
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) )
|
||||
|
||||
return boost::detail::addressof_impl<T>::f( v, 0 );
|
||||
|
||||
#else
|
||||
|
||||
return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct addressof_addp
|
||||
{
|
||||
typedef T * type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< class T, std::size_t N >
|
||||
typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] )
|
||||
{
|
||||
return &t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Borland doesn't like casting an array reference to a char reference
|
||||
// but these overloads work around the problem.
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
template<typename T,std::size_t N>
|
||||
T (*addressof(T (&t)[N]))[N]
|
||||
{
|
||||
@ -56,7 +95,7 @@ const T (*addressof(const T (&t)[N]))[N]
|
||||
{
|
||||
return reinterpret_cast<const T(*)[N]>(&t);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// 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
|
||||
// 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:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@ -10,47 +10,6 @@
|
||||
# error Boost result_of - do not include this file!
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
|
||||
// As of N2588, C++0x result_of only supports function call
|
||||
// expressions of the form f(x). This precludes support for member
|
||||
// function pointers, which are invoked with expressions of the form
|
||||
// o->*f(x). This implementation supports both.
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, detail::result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||
>
|
||||
, detail::result_of_decltype_impl<
|
||||
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \
|
||||
static T ## n t ## n; \
|
||||
/**/
|
||||
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
class result_of_decltype_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
{
|
||||
static F f;
|
||||
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
|
||||
public:
|
||||
typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else // defined(BOOST_HAS_DECLTYPE)
|
||||
|
||||
// CWPro8 requires an argument in a function type specialization
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
||||
# define BOOST_RESULT_OF_ARGS void
|
||||
@ -61,22 +20,64 @@ public:
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, boost::detail::result_of_impl<
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)>
|
||||
, boost::detail::result_of_impl<
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
F,
|
||||
F(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)> >::type { };
|
||||
#endif
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
|
||||
#endif // defined(BOOST_HAS_DECLTYPE)
|
||||
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
: mpl::if_<
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, detail::tr1_result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||
>
|
||||
, detail::cpp0x_result_of_impl<
|
||||
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
{
|
||||
typedef decltype(
|
||||
boost::declval<F>()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<T, >() BOOST_PP_INTERCEPT)
|
||||
)
|
||||
) type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||
#endif
|
||||
|
||||
#endif // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
|
||||
#if BOOST_PP_ITERATION() >= 1
|
||||
|
||||
@ -84,14 +85,14 @@ namespace detail {
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
@ -99,7 +100,7 @@ struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (T0::*)
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
FArgs, false>
|
||||
{
|
||||
@ -108,7 +109,7 @@ struct result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (T0::*)
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const,
|
||||
FArgs, false>
|
||||
@ -118,7 +119,7 @@ struct result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (T0::*)
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
volatile,
|
||||
FArgs, false>
|
||||
@ -128,7 +129,7 @@ struct result_of_impl<R (T0::*)
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of_impl<R (T0::*)
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const volatile,
|
||||
FArgs, false>
|
||||
|
@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
@ -22,6 +24,7 @@
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
|
||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
@ -30,14 +33,15 @@
|
||||
namespace boost {
|
||||
|
||||
template<typename F> struct result_of;
|
||||
template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
namespace detail {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
template<typename F, typename FArgs, bool HasResultType> struct result_of_impl;
|
||||
template<typename F> struct result_of_decltype_impl;
|
||||
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
||||
template<typename F> struct cpp0x_result_of_impl;
|
||||
|
||||
template<typename F>
|
||||
struct result_of_void_impl
|
||||
@ -60,10 +64,10 @@ struct result_of_void_impl<R (&)(void)>
|
||||
// Determine the return type of a function pointer or pointer to member.
|
||||
template<typename F, typename FArgs>
|
||||
struct result_of_pointer
|
||||
: result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
||||
: tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct result_of_impl<F, FArgs, true>
|
||||
struct tr1_result_of_impl<F, FArgs, true>
|
||||
{
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
@ -79,10 +83,10 @@ struct result_of_nested_result : F::template result<FArgs>
|
||||
{};
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct result_of_impl<F, FArgs, false>
|
||||
struct tr1_result_of_impl<F, FArgs, false>
|
||||
: mpl::if_<is_function_with_no_args<FArgs>,
|
||||
result_of_void_impl<F>,
|
||||
result_of_nested_result<F, FArgs> >::type
|
||||
result_of_void_impl<F>,
|
||||
result_of_nested_result<F, FArgs> >::type
|
||||
{};
|
||||
|
||||
} // end namespace detail
|
||||
|
@ -5,7 +5,7 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
// See http://www.boost.org/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
@ -8,6 +8,9 @@
|
||||
// 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker
|
||||
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
||||
// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
|
||||
// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
|
||||
// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
|
||||
// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker
|
||||
//
|
||||
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||
@ -19,6 +22,7 @@
|
||||
// contains. More details on these issues are at libs/utility/value_init.htm
|
||||
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
@ -27,10 +31,39 @@
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER >= 1310
|
||||
// It is safe to ignore the following warning from MSVC 7.1 or higher:
|
||||
// "warning C4351: new behavior: elements of array will be default initialized"
|
||||
#pragma warning(disable: 4351)
|
||||
// It is safe to ignore the following MSVC warning, which may pop up when T is
|
||||
// a const type: "warning C4512: assignment operator could not be generated".
|
||||
#pragma warning(disable: 4512)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
|
||||
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
// suggests that a workaround should be applied, because of compiler issues
|
||||
// regarding value-initialization.
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
#endif
|
||||
|
||||
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
// switches the value-initialization workaround either on or off.
|
||||
#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
|
||||
#else
|
||||
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
class value_initialized
|
||||
class initialized
|
||||
{
|
||||
private :
|
||||
struct wrapper
|
||||
@ -39,6 +72,18 @@ class value_initialized
|
||||
typename
|
||||
#endif
|
||||
remove_const<T>::type data;
|
||||
|
||||
wrapper()
|
||||
:
|
||||
data()
|
||||
{
|
||||
}
|
||||
|
||||
wrapper(T const & arg)
|
||||
:
|
||||
data(arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
mutable
|
||||
@ -54,30 +99,25 @@ class value_initialized
|
||||
|
||||
public :
|
||||
|
||||
value_initialized()
|
||||
initialized()
|
||||
{
|
||||
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
std::memset(&x, 0, sizeof(x));
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER >= 1310
|
||||
// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345:
|
||||
// "behavior change: an object of POD type constructed with an initializer of the form ()
|
||||
// will be default-initialized". It is safe to ignore this warning when using value_initialized.
|
||||
#pragma warning(disable: 4345)
|
||||
#endif
|
||||
#endif
|
||||
new (wrapper_address()) wrapper();
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
value_initialized(value_initialized const & arg)
|
||||
initialized(initialized const & arg)
|
||||
{
|
||||
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.
|
||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||
@ -85,25 +125,96 @@ class value_initialized
|
||||
return *this;
|
||||
}
|
||||
|
||||
~value_initialized()
|
||||
~initialized()
|
||||
{
|
||||
wrapper_address()->wrapper::~wrapper();
|
||||
}
|
||||
|
||||
T& data() const
|
||||
T const & data() const
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
}
|
||||
|
||||
void swap(value_initialized & arg)
|
||||
T& data()
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
}
|
||||
|
||||
void swap(initialized & arg)
|
||||
{
|
||||
::boost::swap( this->data(), arg.data() );
|
||||
}
|
||||
|
||||
operator T&() const { return this->data(); }
|
||||
operator T const &() const
|
||||
{
|
||||
return wrapper_address()->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>
|
||||
@ -111,6 +222,7 @@ T const& get ( value_initialized<T> const& x )
|
||||
{
|
||||
return x.data() ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& get ( value_initialized<T>& x )
|
||||
{
|
||||
@ -130,7 +242,7 @@ class initialized_value_t
|
||||
|
||||
template <class T> operator T() const
|
||||
{
|
||||
return get( value_initialized<T>() );
|
||||
return initialized<T>().data();
|
||||
}
|
||||
};
|
||||
|
||||
@ -139,5 +251,8 @@ initialized_value_t const initialized_value = {} ;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#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>
|
||||
<blockquote>
|
||||
<p>
|
||||
<a href="utility.htm#addressof">addressof</a><br>
|
||||
<a href="assert.html">assert</a><br>
|
||||
<a href="base_from_member.html">base_from_member</a><br>
|
||||
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
|
||||
<a href="call_traits.htm">call_traits</a><br>
|
||||
<a href="checked_delete.html">checked_delete</a><br>
|
||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||
<a href="current_function.html">current_function</a><br>
|
||||
<a href="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="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||
<a href="utility.htm#functions_next_prior">next/prior</a><br>
|
||||
<a href="utility.htm#Class_noncopyable">noncopyable</a><br>
|
||||
<a href="operators.htm">operators</a><br>
|
||||
<a href="utility.htm#result_of">result_of</a><br>
|
||||
<a href="swap.html">swap</a><br>
|
||||
<a href="throw_exception.html">throw_exception</a><br>
|
||||
<a href="utility.htm">utility</a><br>
|
||||
<a href="value_init.htm">value_init</a></p>
|
||||
<a href="value_init.htm">value_init</a>
|
||||
</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
|
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;
|
||||
}
|
@ -132,18 +132,18 @@
|
||||
class MyInt
|
||||
: boost::operators<MyInt>
|
||||
{
|
||||
bool operator<(const MyInt& x) const;
|
||||
bool operator<(const MyInt& x) const;
|
||||
bool operator==(const MyInt& x) const;
|
||||
MyInt& operator+=(const MyInt& x);
|
||||
MyInt& operator-=(const MyInt& x);
|
||||
MyInt& operator*=(const MyInt& x);
|
||||
MyInt& operator/=(const MyInt& x);
|
||||
MyInt& operator%=(const MyInt& x);
|
||||
MyInt& operator|=(const MyInt& x);
|
||||
MyInt& operator&=(const MyInt& x);
|
||||
MyInt& operator^=(const MyInt& x);
|
||||
MyInt& operator++();
|
||||
MyInt& operator--();
|
||||
MyInt& operator+=(const MyInt& x);
|
||||
MyInt& operator-=(const MyInt& x);
|
||||
MyInt& operator*=(const MyInt& x);
|
||||
MyInt& operator/=(const MyInt& x);
|
||||
MyInt& operator%=(const MyInt& x);
|
||||
MyInt& operator|=(const MyInt& x);
|
||||
MyInt& operator&=(const MyInt& x);
|
||||
MyInt& operator^=(const MyInt& x);
|
||||
MyInt& operator++();
|
||||
MyInt& operator--();
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
@ -345,7 +345,7 @@ class MyInt
|
||||
</ul>
|
||||
|
||||
<p>As Daniel Krügler pointed out, this technique violates 14.6.5/2
|
||||
and is thus non-portable. The reasoning is, that the operators injected
|
||||
and is thus non-portable. The reasoning is, that the operators injected
|
||||
by the instantiation of e.g.
|
||||
<code>less_than_comparable<myclass></code> can not be found
|
||||
by ADL according to the rules given by 3.4.2/2, since myclass is
|
||||
@ -445,6 +445,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
optional template parameter <code>B</code>, which is not shown, for the
|
||||
<a href="#chaining">base class chaining</a> technique.</p>
|
||||
|
||||
<p>The primary operand type <code>T</code> needs to be of class type,
|
||||
built-in types are not supported.</p>
|
||||
|
||||
<table cellpadding="5" border="1" align="center">
|
||||
<caption>
|
||||
Simple Arithmetic Operator Template Classes
|
||||
@ -917,7 +920,7 @@ T operator+( const T& lhs, const T& rhs )
|
||||
created, <code>operator+=</code> is called on it and it is copied to the
|
||||
function return value (which is another unnamed object of type
|
||||
<code>T</code>). The standard doesn't generally allow the intermediate
|
||||
object to be optimized away:
|
||||
object to be optimized away:
|
||||
|
||||
<blockquote>
|
||||
3.7.2/2: Automatic storage duration<br>
|
||||
@ -928,7 +931,7 @@ T operator+( const T& lhs, const T& rhs )
|
||||
unused, except that a class object or its copy may be eliminated as
|
||||
specified in 12.8.
|
||||
</blockquote>
|
||||
The reference to 12.8 is important for us:
|
||||
The reference to 12.8 is important for us:
|
||||
|
||||
<blockquote>
|
||||
12.8/15: Copying class objects<br>
|
||||
@ -942,7 +945,7 @@ T operator+( const T& lhs, const T& rhs )
|
||||
</blockquote>
|
||||
This optimization is known as the named return value optimization (NRVO),
|
||||
which leads us to the following implementation for
|
||||
<code>operator+</code>:
|
||||
<code>operator+</code>:
|
||||
<pre>
|
||||
T operator+( const T& lhs, const T& rhs )
|
||||
{
|
||||
@ -956,7 +959,7 @@ T operator+( const T& lhs, const T& rhs )
|
||||
even implement it in an incorrect way which makes it useless here.
|
||||
Without the NRVO, the NRVO-friendly code is no worse than the original
|
||||
code showed above, but there is another possible implementation, which
|
||||
has some very special properties:
|
||||
has some very special properties:
|
||||
<pre>
|
||||
T operator+( T lhs, const T& rhs )
|
||||
{
|
||||
@ -982,7 +985,7 @@ T operator+( T lhs, const T& rhs )
|
||||
will force the NRVO-friendly implementation to be used even for compilers
|
||||
that don't implement the NRVO. <br>
|
||||
<br>
|
||||
|
||||
|
||||
<h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3>
|
||||
|
||||
<p>The following templates provide common groups of related operations.
|
||||
@ -1864,7 +1867,7 @@ T operator+( T lhs, const T& rhs )
|
||||
V, D, P, R></a></code></td>
|
||||
|
||||
<td>
|
||||
Supports the operations and has the requirements of
|
||||
Supports the operations and has the requirements of
|
||||
|
||||
<ul>
|
||||
<li><code><a href="#input_iteratable">input_iteratable<T,
|
||||
@ -1878,7 +1881,7 @@ T operator+( T lhs, const T& rhs )
|
||||
"output_iterator_helper">output_iterator_helper<T></a></code></td>
|
||||
|
||||
<td>
|
||||
Supports the operations and has the requirements of
|
||||
Supports the operations and has the requirements of
|
||||
|
||||
<ul>
|
||||
<li><code><a href=
|
||||
@ -1894,7 +1897,7 @@ T operator+( T lhs, const T& rhs )
|
||||
R></a></code></td>
|
||||
|
||||
<td>
|
||||
Supports the operations and has the requirements of
|
||||
Supports the operations and has the requirements of
|
||||
|
||||
<ul>
|
||||
<li><code><a href="#forward_iteratable">forward_iteratable<T,
|
||||
@ -1909,7 +1912,7 @@ T operator+( T lhs, const T& rhs )
|
||||
V, D, P, R></a></code></td>
|
||||
|
||||
<td>
|
||||
Supports the operations and has the requirements of
|
||||
Supports the operations and has the requirements of
|
||||
|
||||
<ul>
|
||||
<li><code><a href=
|
||||
@ -1925,7 +1928,7 @@ T operator+( T lhs, const T& rhs )
|
||||
V, D, P, R></a></code></td>
|
||||
|
||||
<td>
|
||||
Supports the operations and has the requirements of
|
||||
Supports the operations and has the requirements of
|
||||
|
||||
<ul>
|
||||
<li><code><a href=
|
||||
@ -1976,8 +1979,8 @@ struct function_output_iterator
|
||||
template<typename T>
|
||||
function_output_iterator& operator=(T const& value)
|
||||
{
|
||||
this->func(value);
|
||||
return *this;
|
||||
this->func(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2030,7 +2033,7 @@ public:
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Check the <a href="../../status/compiler_status.html">compiler status
|
||||
<p>Check the <a href="http://www.boost.org/development/testing.html">compiler status
|
||||
report</a> for the test results with selected platforms.</p>
|
||||
<hr>
|
||||
|
||||
@ -2130,8 +2133,8 @@ public:
|
||||
<p>Revised: 7 Aug 2008</p>
|
||||
|
||||
<p>Copyright © Beman Dawes, David Abrahams, 1999-2001.</p>
|
||||
<p>Copyright © Daniel Frey, 2002-2008.</p>
|
||||
<p>Use, modification, and distribution is subject to the Boost Software
|
||||
<p>Copyright © Daniel Frey, 2002-2009.</p>
|
||||
<p>Use, modification, and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file
|
||||
<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
@ -70,7 +70,7 @@ struct ref_wrapper
|
||||
|
||||
struct copy_counter {
|
||||
static int count_;
|
||||
copy_counter(copy_counter const& other) {
|
||||
copy_counter(copy_counter const& /*other*/) {
|
||||
++count_;
|
||||
}
|
||||
copy_counter() {}
|
||||
|
22
swap.html
22
swap.html
@ -7,14 +7,18 @@
|
||||
</head>
|
||||
<body>
|
||||
<!-- Page header -->
|
||||
<h2>
|
||||
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/>
|
||||
Header <<a href="../../boost/swap.hpp">boost/swap.hpp</a>>
|
||||
</h2>
|
||||
|
||||
<h1>Swap</h1>
|
||||
|
||||
<p>
|
||||
<tt>template<class T> void swap(T& <em>left</em>, T& <em>right</em>);</tt>
|
||||
</p>
|
||||
|
||||
<!-- Intoduction -->
|
||||
<!-- Introduction -->
|
||||
<p>
|
||||
The template function <tt>boost::swap</tt> allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, <tt>std::swap</tt> is used.
|
||||
</p>
|
||||
@ -24,10 +28,10 @@
|
||||
<p>
|
||||
The generic <tt>std::swap</tt> function requires that the elements to be swapped are assignable and copy constructible. It is usually implemented using one copy construction and two assignments - this is often both unnecessarily restrictive and unnecessarily slow. In addition, where the generic swap implementation provides only the basic guarantee, specialized swap functions are often able to provide the no-throw exception guarantee (and it is considered best practice to do so where possible<sup><a href="#ref1">1</a></sup>).</p>
|
||||
<p>
|
||||
The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces.
|
||||
The alternative to using argument dependent lookup in this situation is to provide a template specialization of <tt>std::swap</tt> for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces.
|
||||
</p>
|
||||
<p>
|
||||
<tt>boost::swap</tt> also supports swapping built-in arrays. Note that <tt>std::swap</tt> doesn't yet do so, but a request to add an overload of <tt>std::swap</tt> for built-in arrays has been well-received by the Library Working Group of the C++ Standards Committee<sup><a href="#ref2">2</a></sup>.
|
||||
<tt>boost::swap</tt> also supports swapping built-in arrays. Note that <tt>std::swap</tt> originally did not do so, but a request to add an overload of <tt>std::swap</tt> for built-in arrays has been accepted by the C++ Standards Committee<sup><a href="#ref2">2</a></sup>.
|
||||
</p>
|
||||
|
||||
<!-- Exception Safety -->
|
||||
@ -45,11 +49,11 @@
|
||||
</ul>
|
||||
<p>Or:</p>
|
||||
<ul>
|
||||
<li>A function with the signature <tt>swap(T&,T&)</tt> is available via argument dependent lookup</li>
|
||||
<li>A function with the signature <tt>swap(T&,T&)</tt> is available via argument dependent lookup</li>
|
||||
</ul>
|
||||
<p>Or:</p>
|
||||
<ul>
|
||||
<li>A template specialization of std::swap exists for T</li>
|
||||
<li>A template specialization of <tt>std::swap</tt> exists for T</li>
|
||||
</ul>
|
||||
<p>Or:</p>
|
||||
<ul>
|
||||
@ -73,20 +77,20 @@
|
||||
<em><a href="mailto:Joseph.Gauterin@googlemail.com">Joseph Gauterin</a></em> - for the initial idea, implementation, tests, and documentation
|
||||
</li>
|
||||
<li>
|
||||
<em>Steven Wanatabe</em> - for the idea to make boost::swap less specialized than std::swap, thereby allowing the function to have the name 'swap' without introducing ambiguity
|
||||
<em>Steven Watanabe</em> - for the idea to make <tt>boost::swap</tt> less specialized than <tt>std::swap</tt>, thereby allowing the function to have the name 'swap' without introducing ambiguity
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- References -->
|
||||
<hr/>
|
||||
<p><sup><a id="ref1"/>[1]</sup>Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"</p>
|
||||
<p><sup><a id="ref2"/>[2]</sup><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#809">LWG issue 809 (std::swap should be overloaded for array types)</a></p>
|
||||
<p><sup><a id="ref2"/>[2]</sup><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809">LWG Defect Report 809 (std::swap should be overloaded for array types)</a></p>
|
||||
|
||||
<!-- Copyright info -->
|
||||
<hr/>
|
||||
<p>Revised: 4 August 2008</p>
|
||||
<p>Revised: 08 September 2009</p>
|
||||
<p>
|
||||
Copyright 2007, 2008 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0.
|
||||
Copyright 2007 - 2009 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)
|
||||
</p>
|
||||
|
||||
|
@ -29,5 +29,9 @@ test-suite utility/swap
|
||||
[ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run std_vector_of_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run swap_arrays.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run array_of_array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run array_of_array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
[ run array_of_template.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
|
||||
;
|
||||
|
@ -4,6 +4,8 @@
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
|
||||
|
||||
#include <boost/utility/swap.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
@ -33,32 +35,8 @@ namespace std
|
||||
}
|
||||
}
|
||||
|
||||
// Tests swapping 1-dimensional arrays.
|
||||
void test_swapping_1D_arrays()
|
||||
{
|
||||
const std::size_t dimension = 2;
|
||||
const swap_test_class initial_array1[dimension] = { swap_test_class(1), swap_test_class(2) };
|
||||
const swap_test_class initial_array2[dimension] = { swap_test_class(3), swap_test_class(4) };
|
||||
|
||||
swap_test_class array1[dimension];
|
||||
swap_test_class array2[dimension];
|
||||
|
||||
std::copy(initial_array1, initial_array1 + dimension, array1);
|
||||
std::copy(initial_array2, initial_array2 + dimension, array2);
|
||||
|
||||
swap_test_class::reset();
|
||||
boost::swap(array1, array2);
|
||||
|
||||
BOOST_CHECK(std::equal(array1, array1 + dimension, initial_array2));
|
||||
BOOST_CHECK(std::equal(array2, array2 + dimension, initial_array1));
|
||||
|
||||
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), dimension);
|
||||
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
|
||||
}
|
||||
|
||||
|
||||
// Tests swapping 2-dimensional arrays.
|
||||
void test_swapping_2D_arrays()
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
const std::size_t first_dimension = 3;
|
||||
const std::size_t second_dimension = 4;
|
||||
@ -76,7 +54,6 @@ void test_swapping_2D_arrays()
|
||||
ptr2[i].set_data( static_cast<int>(i + number_of_elements) );
|
||||
}
|
||||
|
||||
swap_test_class::reset();
|
||||
boost::swap(array1, array2);
|
||||
|
||||
for (std::size_t i = 0; i < number_of_elements; ++i)
|
||||
@ -87,14 +64,6 @@ void test_swapping_2D_arrays()
|
||||
|
||||
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements);
|
||||
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
test_swapping_1D_arrays();
|
||||
test_swapping_2D_arrays();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
42
swap/test/array_of_array_of_int.cpp
Normal file
42
swap/test/array_of_array_of_int.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Tests swapping an array of arrays of integers by means of boost::swap.
|
||||
|
||||
#include <boost/utility/swap.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <algorithm> //for std::copy and std::equal
|
||||
#include <cstddef> //for std::size_t
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
const std::size_t first_dimension = 3;
|
||||
const std::size_t second_dimension = 4;
|
||||
const std::size_t number_of_elements = first_dimension * second_dimension;
|
||||
|
||||
int array1[first_dimension][second_dimension];
|
||||
int array2[first_dimension][second_dimension];
|
||||
|
||||
int* const ptr1 = array1[0];
|
||||
int* const ptr2 = array2[0];
|
||||
|
||||
for (std::size_t i = 0; i < number_of_elements; ++i)
|
||||
{
|
||||
ptr1[i] = static_cast<int>(i);
|
||||
ptr2[i] = static_cast<int>(i + number_of_elements);
|
||||
}
|
||||
|
||||
boost::swap(array1, array2);
|
||||
|
||||
for (std::size_t i = 0; i < number_of_elements; ++i)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(ptr1[i], static_cast<int>(i + number_of_elements) );
|
||||
BOOST_CHECK_EQUAL(ptr2[i], static_cast<int>(i) );
|
||||
}
|
||||
return 0;
|
||||
}
|
61
swap/test/array_of_class.cpp
Normal file
61
swap/test/array_of_class.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
|
||||
|
||||
#include <boost/utility/swap.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
//Put test class in the global namespace
|
||||
#include "./swap_test_class.hpp"
|
||||
|
||||
#include <algorithm> //for std::copy and std::equal
|
||||
#include <cstddef> //for std::size_t
|
||||
|
||||
//Provide swap function in both the namespace of swap_test_class
|
||||
//(which is the global namespace), and the std namespace.
|
||||
//It's common to provide a swap function for a class in both
|
||||
//namespaces. Scott Meyers recommends doing so: Effective C++,
|
||||
//Third Edition, item 25, "Consider support for a non-throwing swap".
|
||||
void swap(swap_test_class& left, swap_test_class& right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
void swap(swap_test_class& left, swap_test_class& right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
const std::size_t array_size = 2;
|
||||
const swap_test_class initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) };
|
||||
const swap_test_class initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
|
||||
|
||||
swap_test_class array1[array_size];
|
||||
swap_test_class array2[array_size];
|
||||
|
||||
std::copy(initial_array1, initial_array1 + array_size, array1);
|
||||
std::copy(initial_array2, initial_array2 + array_size, array2);
|
||||
|
||||
swap_test_class::reset();
|
||||
boost::swap(array1, array2);
|
||||
|
||||
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
|
||||
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
|
||||
|
||||
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size);
|
||||
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
|
||||
|
||||
return 0;
|
||||
}
|
35
swap/test/array_of_int.cpp
Normal file
35
swap/test/array_of_int.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Tests swapping an array of integers by means of boost::swap.
|
||||
|
||||
#include <boost/utility/swap.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <algorithm> //for std::copy and std::equal
|
||||
#include <cstddef> //for std::size_t
|
||||
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
const std::size_t array_size = 3;
|
||||
const int initial_array1[array_size] = { 1, 2, 3 };
|
||||
const int initial_array2[array_size] = { 4, 5, 6 };
|
||||
|
||||
int array1[array_size];
|
||||
int array2[array_size];
|
||||
|
||||
std::copy(initial_array1, initial_array1 + array_size, array1);
|
||||
std::copy(initial_array2, initial_array2 + array_size, array2);
|
||||
|
||||
boost::swap(array1, array2);
|
||||
|
||||
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
|
||||
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
|
||||
|
||||
return 0;
|
||||
}
|
71
swap/test/array_of_template.cpp
Normal file
71
swap/test/array_of_template.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Tests swapping an array of swap_test_template<int> objects by means of boost::swap.
|
||||
|
||||
#include <boost/utility/swap.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
//Put test class in the global namespace
|
||||
#include "./swap_test_class.hpp"
|
||||
|
||||
#include <algorithm> //for std::copy and std::equal
|
||||
#include <cstddef> //for std::size_t
|
||||
|
||||
template <class T>
|
||||
class swap_test_template
|
||||
{
|
||||
public:
|
||||
typedef T template_argument;
|
||||
swap_test_class swap_test_object;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline bool operator==(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
|
||||
{
|
||||
return lhs.swap_test_object == rhs.swap_test_object;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool operator!=(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//Provide swap function in the namespace of swap_test_template
|
||||
//(which is the global namespace). Note that it isn't allowed to put
|
||||
//an overload of this function within the std namespace.
|
||||
template <class T>
|
||||
void swap(swap_test_template<T>& left, swap_test_template<T>& right)
|
||||
{
|
||||
left.swap_test_object.swap(right.swap_test_object);
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
const std::size_t array_size = 2;
|
||||
const swap_test_template<int> initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) };
|
||||
const swap_test_template<int> initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
|
||||
|
||||
swap_test_template<int> array1[array_size];
|
||||
swap_test_template<int> array2[array_size];
|
||||
|
||||
std::copy(initial_array1, initial_array1 + array_size, array1);
|
||||
std::copy(initial_array2, initial_array2 + array_size, array2);
|
||||
|
||||
swap_test_class::reset();
|
||||
boost::swap(array1, array2);
|
||||
|
||||
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
|
||||
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
|
||||
|
||||
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size);
|
||||
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
||||
// Copyright (c) 2008 - 2010 Joseph Gauterin, Niels Dekker
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -17,9 +17,9 @@
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
typedef std::bitset<8> bitset_type;
|
||||
const bitset_type initial_value1 = 1ul;
|
||||
const bitset_type initial_value2 = 2ul;
|
||||
|
||||
const bitset_type initial_value1 = 1;
|
||||
const bitset_type initial_value2 = 2;
|
||||
|
||||
bitset_type object1 = initial_value1;
|
||||
bitset_type object2 = initial_value2;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
class swap_test_class
|
||||
{
|
||||
int m_data;
|
||||
int m_data;
|
||||
public:
|
||||
explicit swap_test_class(int arg = 0)
|
||||
:
|
||||
|
@ -11,7 +11,9 @@ import testing ;
|
||||
# Please keep the tests ordered by filename
|
||||
test-suite utility
|
||||
:
|
||||
[ run ../addressof_fn_test.cpp ]
|
||||
[ run ../addressof_test.cpp ]
|
||||
[ run ../addressof_test2.cpp ]
|
||||
[ run ../assert_test.cpp ]
|
||||
[ run ../base_from_member_test.cpp ]
|
||||
[ run ../binary_search_test.cpp ]
|
||||
@ -30,9 +32,13 @@ test-suite utility
|
||||
[ compile result_of_test.cpp ]
|
||||
[ run ../shared_iterator_test.cpp ]
|
||||
[ run ../value_init_test.cpp ]
|
||||
[ run ../value_init_workaround_test.cpp ]
|
||||
[ run ../initialized_test.cpp ]
|
||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||
[ run ../verify_test.cpp ]
|
||||
;
|
||||
|
||||
|
0
test/next_prior_test.cpp
Executable file → Normal file
0
test/next_prior_test.cpp
Executable file → Normal file
@ -5,6 +5,8 @@
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <utility>
|
||||
@ -96,6 +98,11 @@ struct no_result_type_or_result_of
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -106,6 +113,11 @@ struct no_result_type_or_result_of_template
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct X {};
|
||||
@ -131,9 +143,21 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
|
||||
// Prior to decltype, result_of could not deduce the return type
|
||||
// nullary function objects unless they exposed a result_type.
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
|
||||
@ -145,11 +169,14 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
|
||||
|
||||
// Prior to decltype, result_of ignored a nested result<> if
|
||||
// result_type was defined. After decltype, result_of deduces the
|
||||
// actual return type of the function object, ignoring both
|
||||
// result<> and result_type.
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
|
||||
#else
|
||||
@ -168,6 +195,17 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
@ -177,11 +215,23 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
|
||||
|
||||
typedef int (*pf_t)(int);
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
|
||||
|
||||
#if defined(BOOST_HAS_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
|
||||
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(void)>::type, unsigned int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of(double)>::type, short>::value));
|
||||
@ -192,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<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value));
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int const&)>::type, long>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int const&)>::type, long>::value));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -1,58 +1,15 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Boost: throw_exception.hpp documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
|
||||
</td>
|
||||
<td align="center">
|
||||
<h1>throw_exception.hpp</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" height="64"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
The header <STRONG><boost/throw_exception.hpp></STRONG> defines the
|
||||
helper function <STRONG>boost::throw_exception</STRONG>. It is intended to be
|
||||
used in Boost libraries that need to throw exceptions, but support
|
||||
configurations and platforms where exceptions aren't available, as indicated by
|
||||
the presence of the <STRONG>BOOST_NO_EXCEPTIONS</STRONG> <A href="../config/config.htm#macro_ref">
|
||||
configuration macro</A>.
|
||||
</p>
|
||||
<P>When <STRONG>BOOST_NO_EXCEPTIONS</STRONG> is not defined, <tt>boost::throw_exception(e)</tt>
|
||||
is equivalent to <tt>throw e</tt>. Otherwise, the function is left undefined,
|
||||
and the user is expected to supply an appropriate definition. Callers of <tt>throw_exception</tt>
|
||||
are allowed to assume that the function never returns; therefore, if the
|
||||
user-defined <tt>throw_exception</tt> returns, the behavior is undefined.</P>
|
||||
<h3><a name="Synopsis">Synopsis</a></h3>
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
void throw_exception(std::exception const & e); // user defined
|
||||
|
||||
#else
|
||||
|
||||
template<class E> void throw_exception(E const & e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
</pre>
|
||||
<p><br>
|
||||
<small>Copyright <20> 2002 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
<head>
|
||||
<meta http-equiv=refresh content="0; URL=../exception/doc/throw_exception.html">
|
||||
<title>Automatic redirection</title>
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../exception/doc/throw_exception.html">throw_exception.html</a>. <hr>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</html>
|
||||
|
98
utility.htm
98
utility.htm
@ -151,37 +151,95 @@ void f() {
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> defines the result type
|
||||
of the expression <code>f(t1, t2,
|
||||
...,t<em>N</em>)</code>. The implementation permits
|
||||
...,t<em>N</em>)</code>. This implementation permits
|
||||
the type <code>F</code> to be a function pointer,
|
||||
function reference, member function pointer, or class
|
||||
type.</p> <p>If your compiler does not support
|
||||
<code>decltype</code>, then when <code>F</code> is a
|
||||
class type with a member type <code>result_type</code>,
|
||||
type. By default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>. Class template <code>result_of</code>
|
||||
resides in the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
|
||||
<p>If your compiler supports <code>decltype</code>,
|
||||
then you can enable automatic result type deduction by
|
||||
defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>,
|
||||
as in the following example.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
struct functor {
|
||||
template<class T>
|
||||
T operator()(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>If <code>decltype</code> is not enabled,
|
||||
then automatic result type deduction of function
|
||||
objects is not possible. Instead, <code>result_of</code>
|
||||
uses the following protocol to allow the programmer to
|
||||
specify a type. When <code>F</code> is a class type with a
|
||||
member type <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is
|
||||
<code>F::result_type</code>. When <code>F</code>
|
||||
does not contain <code>result_type</code>,
|
||||
<code>F::result_type</code>. When <code>F</code> does
|
||||
not contain <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||
T2, ..., T<em>N</em>)>::type</code> when
|
||||
<code><em>N</em> > 0</code> or <code>void</code>
|
||||
when <code><em>N</em> = 0</code>. 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>
|
||||
when <code><em>N</em> = 0</code>. Note that it is the
|
||||
responsibility of the programmer to ensure that
|
||||
function objects accurately advertise their result
|
||||
type via this protocol, as in the following
|
||||
example.</p>
|
||||
|
||||
<p>Class template <code>result_of</code> resides in
|
||||
the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
|
||||
default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>.</p>
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result;
|
||||
|
||||
template<class F, class T>
|
||||
struct result<F(T)> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T operator()(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<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>
|
||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||
|
206
value_init.htm
206
value_init.htm
@ -33,6 +33,7 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
||||
<li><a href="#initialized"><code>template class initialized<T></code></a></li>
|
||||
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||
|
||||
</ul>
|
||||
@ -123,6 +124,12 @@ constructed by the following declaration:
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
The template <a href="#initialized"><code>initialized</code></a>
|
||||
offers both value-initialization and direct-initialization.
|
||||
It is especially useful as a data member type, allowing the very same object
|
||||
to be either direct-initialized or value-initialized.
|
||||
</p>
|
||||
<p>
|
||||
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||
allows value-initializing a variable as follows:
|
||||
<pre>
|
||||
@ -216,44 +223,98 @@ it <em>may</em> in practice still be left uninitialized, because of those
|
||||
compiler issues! It's hard to make a general statement on what those issues
|
||||
are like, because they depend on the compiler you are using, its version number,
|
||||
and the type of object you would like to have value-initialized.
|
||||
Compilers usually support value-initialization for built-in types properly.
|
||||
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
|
||||
be partially, or even entirely left uninitialized, when they should be value-initialized.
|
||||
All compilers we have tested so far support value-initialization for arithmetic types properly.
|
||||
However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
|
||||
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
|
||||
go wrong on various compilers.
|
||||
</p>
|
||||
<p>
|
||||
We have encountered issues regarding value-initialization on compilers by
|
||||
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
|
||||
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
|
||||
<tr><td>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
|
||||
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
|
||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
|
||||
<br>
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
|
||||
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
|
||||
<br>Reported by Jonathan Wakely, 2006-12-07
|
||||
<br>
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
|
||||
GCC Bug 33916 - Default constructor fails to initialize array members</a>
|
||||
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
|
||||
<br>
|
||||
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
|
||||
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
|
||||
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
|
||||
<br>
|
||||
</td></tr></table>
|
||||
At the moment of writing, May 2010, the following reported issues regarding
|
||||
value-initialization are still there in current compiler releases:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
|
||||
Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
|
||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
|
||||
</li><li>
|
||||
<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
|
||||
Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
|
||||
<br>Reported by Sylvester Hesp, 2009
|
||||
</li><li>
|
||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
|
||||
Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
|
||||
<br>Reported by Alex Vakulenko, 2009
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
|
||||
Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
|
||||
<br>Reported by Niels Dekker (LKEB), 2010
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851">
|
||||
Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a>
|
||||
<br>Reported by Niels Dekker, 2010
|
||||
</li><li>
|
||||
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279">
|
||||
Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a>
|
||||
<br>Reported by Niels Dekker, 2010
|
||||
</li><li>
|
||||
Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate.
|
||||
<br>Reported to Steve Clamage by Niels Dekker, 2010
|
||||
</li><li>
|
||||
IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate.
|
||||
<br>Reported to Michael Wong by Niels Dekker, 2010
|
||||
</li><li>
|
||||
Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error
|
||||
on Intel 11.1.
|
||||
<br>Reported by John Maddock, 2010
|
||||
</li>
|
||||
</ul>
|
||||
Note that all known GCC issues regarding value-initialization are
|
||||
fixed with GCC version 4.4, including
|
||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>.
|
||||
Clang also has completely implemented value-initialization, as far as we know,
|
||||
now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.
|
||||
</p><p>
|
||||
|
||||
New versions of <code>value_initialized</code>
|
||||
(Boost release version 1.35 or higher)
|
||||
offer a workaround to these issues: <code>value_initialized</code> will now clear
|
||||
its internal data, prior to constructing the object that it contains.
|
||||
offer a workaround to these issues: <code>value_initialized</code> may now clear
|
||||
its internal data, prior to constructing the object that it contains. It will do
|
||||
so for those compilers that need to have such a workaround, based on the
|
||||
<a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects"
|
||||
>compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||
</p>
|
||||
|
||||
<h2><a name="types"></a>Types and objects</h2>
|
||||
|
||||
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
|
||||
|
||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&() const { return x ; }<br> T& data() const { return x ; }<br> void swap( value_initialized<T>& );<br><br> private :<br> <i>unspecified</i> x ;<br>} ;<br><br>template<class T><br>T const& get ( value_initialized<T> const& x )<br>{<br> return x.data() ;<br>}<br><br>template<class T><br>T& get ( value_initialized<T>& x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
|
||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{
|
||||
<br> public :
|
||||
<br> value_initialized() : x() {}
|
||||
<br> operator T const &() const { return x ; }
|
||||
<br> operator T&() { return x ; }
|
||||
<br> T const &data() const { return x ; }
|
||||
<br> T& data() { return x ; }
|
||||
<br> void swap( value_initialized<T>& );
|
||||
<br>
|
||||
<br> private :
|
||||
<br> <i>unspecified</i> x ;
|
||||
<br>} ;
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T const& get ( value_initialized<T> const& x )
|
||||
<br>{
|
||||
<br> return x.data() ;
|
||||
<br>}
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T& get ( value_initialized<T>& x )
|
||||
<br>{
|
||||
<br> return x.data() ;
|
||||
<br>}
|
||||
<br>
|
||||
<br>} // namespace boost
|
||||
<br></pre>
|
||||
|
||||
<p>An object of this template class is a <code>T</code>-wrapper convertible
|
||||
to <code>'T&'</code> whose wrapped object (data member of type <code>T</code>)
|
||||
@ -271,7 +332,8 @@ its internal data, prior to constructing the object that it contains.
|
||||
<code>T&</code>, the member function <code>data()</code>, or the
|
||||
non-member function <code>get()</code>: </p>
|
||||
|
||||
<pre>void watch(int);<br>value_initialized<int> x;<br><br>watch(x) ; // operator T& used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
|
||||
<pre>void watch(int);<br>value_initialized<int> x;
|
||||
<br><br>watch(x) ; // operator T& used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
|
||||
|
||||
<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
|
||||
Mutable objects can be modified directly from within the wrapper but constant
|
||||
@ -281,41 +343,84 @@ non-member function <code>get()</code>: </p>
|
||||
is swappable as well, by calling its <code>swap</code> member function
|
||||
as well as by calling <code>boost::swap</code>.</p>
|
||||
|
||||
<pre>value_initialized<int> x ; <br>static_cast<int&>(x) = 1 ; // OK<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> y ; <br>static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&<br>static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
|
||||
<pre>value_initialized<int> x ; <br>static_cast<int&>(x) = 1 ; // OK<br>get(x) = 1 ; // OK
|
||||
<br><br>value_initialized<int const> y ; <br>static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&<br>static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
|
||||
|
||||
<h3>Warning:</h3>
|
||||
|
||||
<p>Both the conversion operator and the <code>data()</code> member function
|
||||
are <code>const</code> in order to allow access to the wrapped object
|
||||
from a constant wrapper:</p>
|
||||
<p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
|
||||
allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
|
||||
both by its conversion operator and its <code>data()</code> member function. For example:</p>
|
||||
|
||||
<pre>void foo(int);<br>value_initialized<int> const x ;<br>foo(x);<br></pre>
|
||||
<pre>value_initialized<int> const x_c ;<br>int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.
|
||||
<br>xr = 2 ; </pre>
|
||||
|
||||
<p>But notice that this conversion operator is to <code>T&</code> although
|
||||
it is itself <code>const</code>. As a consequence, if <code>T</code> is
|
||||
a non-<code>const</code> type, you can modify the wrapped object even from
|
||||
within a constant wrapper:</p>
|
||||
|
||||
<pre>value_initialized<int> const x_c ;<br>int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.<br>xr = 2 ; </pre>
|
||||
|
||||
<p>The reason for this obscure behavior is that some commonly used compilers
|
||||
just don't accept the following valid code:</p>
|
||||
<p>The reason for this obscure behavior was that some compilers
|
||||
didn't accept the following valid code:</p>
|
||||
|
||||
<pre>struct X<br>{<br> operator int&() ;<br> operator int const&() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
|
||||
|
||||
<p>These compilers complain about ambiguity between the conversion operators.
|
||||
This complaint is incorrect, but the only workaround that I know of is
|
||||
to provide only one of them, which leads to the obscure behavior just explained.<br>
|
||||
<p>The current version of <code>value_initialized</code> no longer has this obscure behavior.
|
||||
As compilers nowadays widely support overloading the conversion operator by having a <code>const</code> and a <code>non-const</code> version, we have decided to fix the issue accordingly. So the current version supports the idea of logical constness.
|
||||
<br>
|
||||
</p>
|
||||
|
||||
<h3>Recommended practice: The non-member get() idiom</h3>
|
||||
|
||||
<p>The obscure behavior of being able to modify a non-<code>const</code>
|
||||
wrapped object from within a constant wrapper can be avoided if access to
|
||||
wrapped object from within a constant wrapper (as was supported by previous
|
||||
versions of <code>value_initialized</code>)
|
||||
can be avoided if access to
|
||||
the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
||||
|
||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
||||
|
||||
<h2><a name="initialized"><code>template class initialized<T></code></a></h2>
|
||||
|
||||
<pre>namespace boost {<br><br>template<class T><br>class initialized<br>{
|
||||
<br> public :
|
||||
<br> initialized() : x() {}
|
||||
<br> explicit initialized(T const & arg) : x(arg) {}
|
||||
<br> operator T const &() const;
|
||||
<br> operator T&();
|
||||
<br> T const &data() const;
|
||||
<br> T& data();
|
||||
<br> void swap( value_initialized<T>& );
|
||||
<br>
|
||||
<br> private :
|
||||
<br> <i>unspecified</i> x ;
|
||||
<br>} ;
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T const& get ( initialized<T> const& x );
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>T& get ( initialized<T>& x );
|
||||
<br>
|
||||
<br>} // namespace boost
|
||||
<br></pre>
|
||||
|
||||
The template class <code>boost::initialized<T></code> supports both value-initialization
|
||||
and direct-initialization, so its interface is a superset of the interface
|
||||
of <code>value_initialized<T></code>: Its default-constructor
|
||||
value-initializes the wrapped object just like the default-constructor of
|
||||
<code>value_initialized<T></code>, but <code>boost::initialized<T></code>
|
||||
also offers an extra <code>explicit</code>
|
||||
constructor, which direct-initializes the wrapped object by the specified value.
|
||||
<p>
|
||||
|
||||
<code>initialized<T></code> is especially useful when the wrapped
|
||||
object must be either value-initialized or direct-initialized, depending on
|
||||
runtime conditions. For example, <code>initialized<T></code> could
|
||||
hold the value of a data member that may be value-initialized by some
|
||||
constructors, and direct-initialized by others.
|
||||
On the other hand, if it is known beforehand that the
|
||||
object must <i>always</i> be value-initialized, <code>value_initialized<T></code>
|
||||
may be preferable. And if the object must always be
|
||||
direct-initialized, none of the two wrappers really needs to be used.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||
|
||||
<pre>
|
||||
@ -375,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
|
||||
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||
</p>
|
||||
<p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
|
||||
Jeffrey Hellrung.
|
||||
</p>
|
||||
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||
</p>
|
||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
||||
@ -383,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>Revised 28 August 2008</p>
|
||||
<p>Revised 30 May 2010</p>
|
||||
|
||||
<p>© Copyright Fernando Cacciola, 2002, 2008.</p>
|
||||
<p>© Copyright Fernando Cacciola, 2002 - 2010.</p>
|
||||
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||
@ -394,4 +502,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -22,16 +22,16 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
// Sample POD type
|
||||
//
|
||||
struct POD
|
||||
{
|
||||
POD () : c(0), i(0), f(0) {}
|
||||
POD () : f(0), c(0), i(0){}
|
||||
|
||||
POD ( char c_, int i_, float f_ ) : c(c_), i(i_), f(f_) {}
|
||||
POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {}
|
||||
|
||||
friend std::ostream& operator << ( std::ostream& os, POD const& pod )
|
||||
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
|
||||
@ -215,7 +215,7 @@ template<class T>
|
||||
void check_initialized_value ( T const& y )
|
||||
{
|
||||
T initializedValue = boost::initialized_value ;
|
||||
BOOST_CHECK ( y == initializedValue ) ;
|
||||
BOOST_TEST ( y == initializedValue ) ;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& )
|
||||
template<class T>
|
||||
bool test ( T const& y, T const& z )
|
||||
{
|
||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||
const int errors_before_test = boost::detail::test_errors();
|
||||
|
||||
check_initialized_value(y);
|
||||
|
||||
boost::value_initialized<T> x ;
|
||||
BOOST_CHECK ( y == x ) ;
|
||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||
BOOST_TEST ( y == x ) ;
|
||||
BOOST_TEST ( y == boost::get(x) ) ;
|
||||
|
||||
static_cast<T&>(x) = z ;
|
||||
boost::get(x) = z ;
|
||||
BOOST_CHECK ( x == z ) ;
|
||||
BOOST_TEST ( x == z ) ;
|
||||
|
||||
boost::value_initialized<T> const x_c ;
|
||||
BOOST_CHECK ( y == x_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
||||
T& x_c_ref = x_c ;
|
||||
BOOST_TEST ( y == x_c ) ;
|
||||
BOOST_TEST ( y == boost::get(x_c) ) ;
|
||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||
x_c_ref = z ;
|
||||
BOOST_CHECK ( x_c == z ) ;
|
||||
BOOST_TEST ( x_c == z ) ;
|
||||
|
||||
boost::value_initialized<T> const copy1 = x;
|
||||
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
||||
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
||||
|
||||
boost::value_initialized<T> copy2;
|
||||
copy2 = x;
|
||||
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
||||
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||
|
||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||
BOOST_CHECK ( y == *ptr ) ;
|
||||
BOOST_TEST ( y == *ptr ) ;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
boost::value_initialized<T const> cx ;
|
||||
BOOST_CHECK ( y == cx ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
||||
BOOST_TEST ( y == cx ) ;
|
||||
BOOST_TEST ( y == boost::get(cx) ) ;
|
||||
|
||||
boost::value_initialized<T const> const cx_c ;
|
||||
BOOST_CHECK ( y == cx_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
||||
BOOST_TEST ( y == cx_c ) ;
|
||||
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
||||
#endif
|
||||
|
||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||
return boost::detail::test_errors() == errors_before_test ;
|
||||
}
|
||||
|
||||
int test_main(int, char **)
|
||||
int main(int, char **)
|
||||
{
|
||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78) ) ) ;
|
||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
|
||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
|
||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
|
||||
StringAndInt stringAndInt0;
|
||||
StringAndInt stringAndInt1;
|
||||
stringAndInt0.i = 0;
|
||||
stringAndInt1.i = 1;
|
||||
stringAndInt1.s = std::string("1");
|
||||
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
||||
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
||||
|
||||
StructWithDestructor structWithDestructor0;
|
||||
StructWithDestructor structWithDestructor1;
|
||||
structWithDestructor0.i = 0;
|
||||
structWithDestructor1.i = 1;
|
||||
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
||||
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
||||
|
||||
StructWithVirtualFunction structWithVirtualFunction0;
|
||||
StructWithVirtualFunction structWithVirtualFunction1;
|
||||
structWithVirtualFunction0.i = 0;
|
||||
structWithVirtualFunction1.i = 1;
|
||||
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
|
||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||
get(swapFunctionCallTester1).data = 1;
|
||||
get(swapFunctionCallTester2).data = 2;
|
||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
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