Compare commits

...

43 Commits

Author SHA1 Message Date
62a15de321 Release 1.44.0
[SVN r64846]
2010-08-16 15:03:16 +00:00
d7cf3628f7 Merge some link fixes.
[64006] and [64059].


[SVN r64061]
2010-07-15 21:19:14 +00:00
b273cd3914 Merged value_init fixes (extra tests + documentation) from trunk, see #3472, #3869.
[SVN r63638]
2010-07-04 21:56:44 +00:00
ca7db1f361 Merged value_init fixes from trunk, ref #3472, #3869.
[SVN r63637]
2010-07-04 21:50:38 +00:00
2a7e81e07f Merged revisions 61248 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r61248 | eric_niebler | 2010-04-13 08:01:11 -0700 (Tue, 13 Apr 2010) | 1 line
  
  add tr1_result_of that always behaves as TR1 specifies, fix Boost.TR1's result_of to use tr1_result_of
........


[SVN r62137]
2010-05-22 05:35:51 +00:00
13da21e7b1 Revert changes to result_of. Reopens #862, #1310, #1535.
[SVN r61149]
2010-04-08 21:59:33 +00:00
b3ffef536d Merged std_bitset.cpp (boost::swap test) from trunk r60292 through r60334 and r61065 through r61076, including #3984 fix.
[SVN r61077]
2010-04-05 19:21:12 +00:00
e2c98762db Revert [60052] as it isn't as uncontroversial as I thought.
[SVN r60314]
2010-03-07 16:22:34 +00:00
8af4250c3c Suppress/fix some msvc and gcc compiler warnings ([57494]).
[SVN r60291]
2010-03-07 12:13:29 +00:00
e30889304c Merge some tests for unwrap ([47296], [47297])
[SVN r60290]
2010-03-07 12:11:44 +00:00
b4dee80e61 Merge various result_of changes.
- [42234] Reduce header dependencies, from Shunsuke Sogame. Fixes #1535
 - [45256] result_of implementation that makes use of C++0x decltype, from Daniel Walker. Fixes #862.
 - [48620] Fix result_of to work with const-qualified function pointers. Fixes #1310
 - [60052] Remove use of deprecated config macro in result_of.



[SVN r60289]
2010-03-07 12:08:00 +00:00
a47dce770c Fix some whitespace differences between trunk and release.
[SVN r58878]
2010-01-10 19:17:23 +00:00
dab1e8e522 Merging changes from trunk.
[SVN r58421]
2009-12-16 22:26:57 +00:00
583422cda2 Add swap to utility index page.
Merged revisions 47093 via svnmerge from 
https://svn.boost.org/svn/boost/trunk


[SVN r57482]
2009-11-08 11:45:20 +00:00
ee146a02a1 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
c131cbd0b2 Merged value_init from the trunk, including fix of #2548, regarding "const value_initialized".
[SVN r56547]
2009-10-03 10:19:09 +00:00
f8bef7ba95 Merged value_init_test from trunk, inc. [51356], anticipating the fix of ticket #2548, which will remove implicit conversion from const value_initialized<T> to non-const T&.
[SVN r56543]
2009-10-03 09:08:10 +00:00
e54cbf3053 Merged Swap documentation from trunk, including revision [56107] and [56108].
[SVN r56541]
2009-10-03 08:15:14 +00:00
d5291d08b8 Merged 52463
[SVN r55485]
2009-08-09 13:45:03 +00:00
61755605af Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
cd12e322bd Merging in changes trunk updates: adding standard error_info typedefs, updating the documentation.
[SVN r55094]
2009-07-22 20:55:50 +00:00
8cb975feb7 Merge [47295] to release.
[SVN r53602]
2009-06-03 14:45:12 +00:00
ffe151458e Use local copy of the valid HTML 4.01 icon, and make sure all the pages
that use it are valid.

Merged revisions 53047-53048 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53047 | danieljames | 2009-05-16 15:17:20 +0100 (Sat, 16 May 2009) | 1 line
  
  Fix some validation errors.
........
  r53048 | danieljames | 2009-05-16 15:23:59 +0100 (Sat, 16 May 2009) | 1 line
  
  Use a local copy of the valid HTML 4.01 icon.
........


[SVN r53258]
2009-05-25 20:06:26 +00:00
4003a9f74a Merge [53060] from the trunk.
[SVN r53197]
2009-05-23 05:36:13 +00:00
211eb04f33 Merge [44151], [48025] to release. Closes #3064.
[SVN r53172]
2009-05-22 09:00:11 +00:00
e57213b298 Fixed almost all tab and min/max issues found by inspect tool
[SVN r53142]
2009-05-20 19:41:20 +00:00
51f9adbfa1 Merged revisions 52837 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r52837 | eric_niebler | 2009-05-07 10:47:08 -0700 (Thu, 07 May 2009) | 1 line
  
  eliminate noisy warning on msvc
........


[SVN r53054]
2009-05-16 18:15:17 +00:00
eaaf17a88f tuning up cmakefiles for unordered, utility
[SVN r53008]
2009-05-15 00:21:14 +00:00
48cfd42123 tune up ptr_container, utility tests in cmakeland
[SVN r53007]
2009-05-14 23:56:22 +00:00
76aa5d2f27 more cmakefile tweaks
[SVN r52999]
2009-05-14 19:58:42 +00:00
ce67dde4f0 Documentation update
[SVN r52091]
2009-03-31 22:16:49 +00:00
a69e872a91 Merge [51977], [51986], [52010] to release.
[SVN r52040]
2009-03-28 20:53:26 +00:00
e3640e45c2 Merge [51872], [51891] to release. Closes #2878.
[SVN r51907]
2009-03-22 20:05:02 +00:00
b7cd171b2b Merge [51512] to release. Closes #2128.
[SVN r51534]
2009-03-02 16:32:03 +00:00
b2e6a82adb This html was outdated; changed to forward to throw_exception.html documentation from Boost Exception
[SVN r50880]
2009-01-29 19:14:05 +00:00
390372294a merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
ffbbf38e12 Merged new array-of-array tests of swap utility from trunk to release branch, following changeset [49954].
[SVN r50227]
2008-12-09 18:21:25 +00:00
9e73b2c6ae Merged value_initialized::swap from trunk [48424] and [48425], according to ticket #2243, as was agreed with Fernando Cacciola.
[SVN r49967]
2008-11-27 19:37:39 +00:00
633832e872 Merged libs/utility/swap.html from trunk to release (r47094 through r49914)
[SVN r49915]
2008-11-24 16:50:22 +00:00
862cb2a4e0 Merged revisions 49661-49662,49666,49669,49735,49756,49770,49811 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49661 | danieljames | 2008-11-09 12:03:45 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Move hash detail headers out of boost/functional/detail.
........
  r49662 | danieljames | 2008-11-09 12:11:50 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Add a forwarding header for container_fwd.hpp
........
  r49666 | danieljames | 2008-11-09 19:12:05 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Avoid comparing default initialised iterators in position_iterator.
........
  r49669 | danieljames | 2008-11-09 21:57:38 +0000 (Sun, 09 Nov 2008) | 2 lines
  
  Add link to the header to the synopsis in reference documentation.
  Refs #2214
........
  r49735 | danieljames | 2008-11-14 12:51:00 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Explicitly specify the template parameters in the unordered container friend, in order to avoid some warnings.
........
  r49756 | danieljames | 2008-11-14 16:11:16 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Use pragmas to suppress a Visual C++ warning.
........
  r49770 | danieljames | 2008-11-15 13:07:29 +0000 (Sat, 15 Nov 2008) | 1 line
  
  Use the new swap library.
........
  r49811 | danieljames | 2008-11-16 23:10:00 +0000 (Sun, 16 Nov 2008) | 1 line
  
  Fix a typo.
........


[SVN r49855]
2008-11-20 22:53:20 +00:00
b012f16ee5 Merged utility/swap documentation to release branch.
[SVN r49763]
2008-11-15 01:15:54 +00:00
3d96ab26d4 Merged utility/swap tests to release branch.
[SVN r49762]
2008-11-15 01:13:01 +00:00
8652bf51ec Merged utility/swap to release branch.
[SVN r49761]
2008-11-15 01:11:24 +00:00
68 changed files with 2840 additions and 420 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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();
}

View File

@ -281,7 +281,7 @@ object_id_compare::operator ()
}
else
{
return a.second->before( *b.second );
return a.second->before( *b.second ) != 0;
}
}
}

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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&lt;class InPlaceFactory&gt;
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>

View File

@ -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

View File

@ -8,6 +8,9 @@
// See http://www.boost.org/libs/utility/operators.htm for documentation.
// Revision History
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
// 03 Apr 08 Make sure "convertible to bool" is sufficient
// for T::operator<, etc. (Daniel Frey)
// 24 May 07 Changed empty_base to depend on T, see
// http://svn.boost.org/trac/boost/ticket/979
// 21 Oct 02 Modified implementation of operators to allow compilers with a
@ -124,34 +127,34 @@ namespace boost
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable2 : B
{
friend bool operator<=(const T& x, const U& y) { return !(x > y); }
friend bool operator>=(const T& x, const U& y) { return !(x < y); }
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
friend bool operator>(const U& x, const T& y) { return y < x; }
friend bool operator<(const U& x, const T& y) { return y > x; }
friend bool operator<=(const U& x, const T& y) { return !(y < x); }
friend bool operator>=(const U& x, const T& y) { return !(y > x); }
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !(y < x); }
friend bool operator>=(const T& x, const T& y) { return !(x < y); }
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct equality_comparable2 : B
{
friend bool operator==(const U& y, const T& x) { return x == y; }
friend bool operator!=(const U& y, const T& x) { return !(x == y); }
friend bool operator!=(const T& y, const U& x) { return !(y == x); }
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
};
// A macro which produces "name_2left" from "name".
@ -356,7 +359,7 @@ struct equivalent2 : B
{
friend bool operator==(const T& x, const U& y)
{
return !(x < y) && !(x > y);
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
}
};
@ -365,7 +368,7 @@ struct equivalent1 : B
{
friend bool operator==(const T&x, const T&y)
{
return !(x < y) && !(y < x);
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
}
};
@ -373,17 +376,17 @@ template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct partially_ordered2 : B
{
friend bool operator<=(const T& x, const U& y)
{ return (x < y) || (x == y); }
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend bool operator>=(const T& x, const U& y)
{ return (x > y) || (x == y); }
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
friend bool operator>(const U& x, const T& y)
{ return y < x; }
friend bool operator<(const U& x, const T& y)
{ return y > x; }
friend bool operator<=(const U& x, const T& y)
{ return (y > x) || (y == x); }
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
friend bool operator>=(const U& x, const T& y)
{ return (y < x) || (y == x); }
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
@ -392,9 +395,9 @@ struct partially_ordered1 : B
friend bool operator>(const T& x, const T& y)
{ return y < x; }
friend bool operator<=(const T& x, const T& y)
{ return (x < y) || (x == y); }
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend bool operator>=(const T& x, const T& y)
{ return (y < x) || (x == y); }
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
};
// Combined operator classes (contributed by Daryle Walker) ----------------//
@ -580,7 +583,35 @@ struct ordered_euclidian_ring_operators1
: totally_ordered1<T
, euclidian_ring_operators1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct euclidean_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U
, modable2<T, U
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct euclidean_ring_operators1
: ring_operators1<T
, dividable1<T
, modable1<T, B
> > > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidean_ring_operators2
: totally_ordered2<T, U
, euclidean_ring_operators2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidean_ring_operators1
: totally_ordered1<T
, euclidean_ring_operators1<T, B
> > {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct input_iteratable
: equality_comparable1<T
@ -837,6 +868,8 @@ BOOST_OPERATOR_TEMPLATE(field_operators)
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)

View File

@ -173,6 +173,17 @@ class unwrap_reference
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T> inline typename unwrap_reference<T>::type&
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

12
include/boost/swap.hpp Normal file
View File

@ -0,0 +1,12 @@
// Copyright (C) 2007 Joseph Gauterin
//
// 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)
#ifndef BOOST_SWAP_HPP
#define BOOST_SWAP_HPP
#include "boost/utility/swap.hpp"
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -20,10 +20,69 @@
#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)>
: boost::detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type<F>::value)> {};
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
: mpl::if_<
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
, boost::detail::tr1_result_of_impl<
typename remove_cv<F>::type,
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)>
, boost::detail::tr1_result_of_impl<
F,
F(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)> >::type { };
#endif
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
// 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::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 {
# 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 cpp0x_result_of_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_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
@ -32,14 +91,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;
};
@ -47,7 +106,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>
{
@ -56,7 +115,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>
@ -66,7 +125,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>
@ -76,7 +135,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>

View File

@ -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

View File

@ -10,13 +10,18 @@
#define BOOST_RESULT_OF_HPP
#include <boost/config.hpp>
#include <boost/type_traits/ice.hpp>
#include <boost/type.hpp>
#include <boost/preprocessor.hpp>
#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_shifted_params.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#ifndef BOOST_RESULT_OF_NUM_ARGS
# define BOOST_RESULT_OF_NUM_ARGS 10
@ -25,13 +30,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, 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
@ -51,8 +58,13 @@ struct result_of_void_impl<R (&)(void)>
typedef R type;
};
// Determine the return type of a function pointer or pointer to member.
template<typename F, typename FArgs>
struct result_of_impl<F, FArgs, true>
struct result_of_pointer
: tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
template<typename F, typename FArgs>
struct tr1_result_of_impl<F, FArgs, true>
{
typedef typename F::result_type type;
};
@ -68,10 +80,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

View File

@ -0,0 +1,55 @@
// Copyright (C) 2007, 2008 Steven Watanabe, 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)
// For more information, see http://www.boost.org
#ifndef BOOST_UTILITY_SWAP_HPP
#define BOOST_UTILITY_SWAP_HPP
// Note: the implementation of this utility contains various workarounds:
// - swap_impl is put outside the boost namespace, to avoid infinite
// recursion (causing stack overflow) when swapping objects of a primitive
// type.
// - swap_impl has a using-directive, rather than a using-declaration,
// because some compilers (including MSVC 7.1, Borland 5.9.3, and
// Intel 8.1) don't do argument-dependent lookup when it has a
// using-declaration instead.
// - boost::swap has two template arguments, instead of one, to
// avoid ambiguity when swapping objects of a Boost type that does
// not have its own boost::swap overload.
#include <algorithm> //for std::swap
#include <cstddef> //for std::size_t
namespace boost_swap_impl
{
template<class T>
void swap_impl(T& left, T& right)
{
using namespace std;//use std::swap if argument dependent lookup fails
swap(left,right);
}
template<class T, std::size_t N>
void swap_impl(T (& left)[N], T (& right)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
}
namespace boost
{
template<class T1, class T2>
void swap(T1& left, T2& right)
{
::boost_swap_impl::swap_impl(left, right);
}
}
#endif

View File

@ -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

View File

@ -7,6 +7,10 @@
// 21 Ago 2002 (Created) Fernando Cacciola
// 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
@ -18,17 +22,48 @@
// 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>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
#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
@ -37,6 +72,18 @@ class value_initialized
typename
#endif
remove_const<T>::type data;
wrapper()
:
data()
{
}
wrapper(T const & arg)
:
data(arg)
{
}
};
mutable
@ -52,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 );
@ -83,20 +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;
}
operator T&() const { return this->data(); }
T& data()
{
return wrapper_address()->data;
}
void swap(initialized & arg)
{
::boost::swap( this->data(), arg.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>
@ -104,12 +222,19 @@ T const& get ( value_initialized<T> const& x )
{
return x.data() ;
}
template<class T>
T& get ( value_initialized<T>& x )
{
return x.data() ;
}
template<class T>
void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
{
lhs.swap(rhs) ;
}
class initialized_value_t
{
@ -117,7 +242,7 @@ class initialized_value_t
template <class T> operator T() const
{
return get( value_initialized<T>() );
return initialized<T>().data();
}
};
@ -126,5 +251,8 @@ initialized_value_t const initialized_value = {} ;
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#endif

View File

@ -24,6 +24,7 @@
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
<a href="operators.htm">operators</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>

116
initialized_test.cpp Normal file
View 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();
}

View 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;
}

View 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;
}

View File

@ -132,18 +132,18 @@
class MyInt
: boost::operators&lt;MyInt&gt;
{
bool operator&lt;(const MyInt&amp; x) const;
bool operator&lt;(const MyInt&amp; x) const;
bool operator==(const MyInt&amp; x) const;
MyInt&amp; operator+=(const MyInt&amp; x);
MyInt&amp; operator-=(const MyInt&amp; x);
MyInt&amp; operator*=(const MyInt&amp; x);
MyInt&amp; operator/=(const MyInt&amp; x);
MyInt&amp; operator%=(const MyInt&amp; x);
MyInt&amp; operator|=(const MyInt&amp; x);
MyInt&amp; operator&amp;=(const MyInt&amp; x);
MyInt&amp; operator^=(const MyInt&amp; x);
MyInt&amp; operator++();
MyInt&amp; operator--();
MyInt&amp; operator+=(const MyInt&amp; x);
MyInt&amp; operator-=(const MyInt&amp; x);
MyInt&amp; operator*=(const MyInt&amp; x);
MyInt&amp; operator/=(const MyInt&amp; x);
MyInt&amp; operator%=(const MyInt&amp; x);
MyInt&amp; operator|=(const MyInt&amp; x);
MyInt&amp; operator&amp;=(const MyInt&amp; x);
MyInt&amp; operator^=(const MyInt&amp; x);
MyInt&amp; operator++();
MyInt&amp; operator--();
};
</pre>
</blockquote>
@ -345,7 +345,7 @@ class MyInt
</ul>
<p>As Daniel Kr&uuml;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&lt;myclass&gt;</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&lt;float&gt; 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&amp; lhs, const T&amp; 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&amp; lhs, const T&amp; 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&amp; lhs, const T&amp; 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&amp; lhs, const T&amp; rhs )
{
@ -956,7 +959,7 @@ T operator+( const T&amp; lhs, const T&amp; 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&amp; rhs )
{
@ -982,7 +985,7 @@ T operator+( T lhs, const T&amp; 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.
@ -1420,9 +1423,9 @@ T operator+( T lhs, const T&amp; rhs )
<tr>
<td><code><a name=
"euclidian_ring_operators1">euclidian_ring_operators&lt;T&gt;</a></code><br>
"euclidean_ring_operators1">euclidean_ring_operators&lt;T&gt;</a></code><br>
<code>euclidian_ring_operators1&lt;T&gt;</code></td>
<code>euclidean_ring_operators1&lt;T&gt;</code></td>
<td>
<ul>
@ -1439,9 +1442,9 @@ T operator+( T lhs, const T&amp; rhs )
<tr>
<td><code><a name=
"euclidian_ring_operators2">euclidian_ring_operators&lt;T,
"euclidean_ring_operators2">euclidean_ring_operators&lt;T,
U&gt;</a></code><br>
<code>euclidian_ring_operators2&lt;T, U&gt;</code></td>
<code>euclidean_ring_operators2&lt;T, U&gt;</code></td>
<td>
<ul>
@ -1464,14 +1467,14 @@ T operator+( T lhs, const T&amp; rhs )
<tr>
<td><code><a name=
"ordered_euclidian_ring_operators1">ordered_euclidian_ring_operators&lt;T&gt;</a></code><br>
"ordered_euclidean_ring_operators1">ordered_euclidean_ring_operators&lt;T&gt;</a></code><br>
<code>ordered_euclidian_ring_operators1&lt;T&gt;</code></td>
<code>ordered_euclidean_ring_operators1&lt;T&gt;</code></td>
<td>
<ul>
<li><code><a href=
"#euclidian_ring_operators1">euclidian_ring_operators&lt;T&gt;</a></code></li>
"#euclidean_ring_operators1">euclidean_ring_operators&lt;T&gt;</a></code></li>
<li><code><a href=
"#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
@ -1481,14 +1484,14 @@ T operator+( T lhs, const T&amp; rhs )
<tr>
<td><code><a name=
"ordered_euclidian_ring_operators2">ordered_euclidian_ring_operators&lt;T,
"ordered_euclidean_ring_operators2">ordered_euclidean_ring_operators&lt;T,
U&gt;</a></code><br>
<code>ordered_euclidian_ring_operators2&lt;T, U&gt;</code></td>
<code>ordered_euclidean_ring_operators2&lt;T, U&gt;</code></td>
<td>
<ul>
<li><code><a href=
"#euclidian_ring_operators2">euclidian_ring_operators&lt;T,
"#euclidean_ring_operators2">euclidean_ring_operators&lt;T,
U&gt;</a></code></li>
<li><code><a href="#totally_ordered2">totally_ordered&lt;T,
@ -1498,6 +1501,15 @@ T operator+( T lhs, const T&amp; rhs )
</tr>
</table>
<h4>Spelling: euclidean vs. euclidian</h4>
<p>Older versions of the Boost.Operators library used
&quot;<code>euclidian</code>&quot;, but it was pointed out that
&quot;<code>euclidean</code>&quot; is the more common spelling.
To be compatible with older version, the library now supports
both spellings.
</p>
<h3><a name="ex_oprs">Example</a> Templates</h3>
<p>The arithmetic operator class templates <code><a href=
@ -1576,9 +1588,8 @@ T operator+( T lhs, const T&amp; rhs )
<p>The <cite><a href="operators_test.cpp">operators_test.cpp</a></cite>
program demonstrates the use of the arithmetic operator templates, and
can also be used to verify correct operation. Check the <a href=
"../../status/compiler_status.html">compiler status report</a> for the
test results with selected platforms.</p>
can also be used to verify correct operation. Check the compiler status
report for the test results with selected platforms.</p>
<h2><a name="deref">Dereference</a> Operators and Iterator Helpers</h2>
@ -1856,7 +1867,7 @@ T operator+( T lhs, const T&amp; rhs )
V, D, P, R&gt;</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&lt;T,
@ -1870,7 +1881,7 @@ T operator+( T lhs, const T&amp; rhs )
"output_iterator_helper">output_iterator_helper&lt;T&gt;</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=
@ -1886,7 +1897,7 @@ T operator+( T lhs, const T&amp; rhs )
R&gt;</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&lt;T,
@ -1901,7 +1912,7 @@ T operator+( T lhs, const T&amp; rhs )
V, D, P, R&gt;</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=
@ -1917,7 +1928,7 @@ T operator+( T lhs, const T&amp; rhs )
V, D, P, R&gt;</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=
@ -1968,8 +1979,8 @@ struct function_output_iterator
template&lt;typename T&gt;
function_output_iterator&amp; operator=(T const&amp; value)
{
this-&gt;func(value);
return *this;
this-&gt;func(value);
return *this;
}
private:
@ -2119,11 +2130,11 @@ public:
backward-compatible.</p>
<hr>
<p>Revised: 29 Oct 2004</p>
<p>Revised: 7 Aug 2008</p>
<p>Copyright &copy; Beman Dawes, David Abrahams, 1999-2001.</p>
<p>Copyright &copy; Daniel Frey, 2002-2004.</p>
<p>Use, modification, and distribution is subject to the Boost Software
<p>Copyright &copy; 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">

View File

@ -7,6 +7,7 @@
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 03 Apr 08 Added convertible_to_bool (Daniel Frey)
// 01 Oct 01 Added tests for "left" operators
// and new grouped operators. (Helmut Zeisel)
// 20 May 01 Output progress messages. Added tests for new operator
@ -43,6 +44,23 @@ namespace
unsigned char true_value(unsigned char x) { return x; }
unsigned short true_value(unsigned short x) { return x; }
// verify the minimum requirements for some operators
class convertible_to_bool
{
private:
bool _value;
typedef bool convertible_to_bool::*unspecified_bool_type;
void operator!() const;
public:
convertible_to_bool( const bool value ) : _value( value ) {}
operator unspecified_bool_type() const
{ return _value ? &convertible_to_bool::_value : 0; }
};
// The use of operators<> here tended to obscure
// interactions with certain compiler bugs
template <class T>
@ -54,8 +72,10 @@ namespace
explicit Wrapped1( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped1& x) const { return _value < x._value; }
bool operator==(const Wrapped1& x) const { return _value == x._value; }
convertible_to_bool operator<(const Wrapped1& x) const
{ return _value < x._value; }
convertible_to_bool operator==(const Wrapped1& x) const
{ return _value == x._value; }
Wrapped1& operator+=(const Wrapped1& x)
{ _value += x._value; return *this; }
@ -97,8 +117,10 @@ namespace
explicit Wrapped2( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped2& x) const { return _value < x._value; }
bool operator==(const Wrapped2& x) const { return _value == x._value; }
convertible_to_bool operator<(const Wrapped2& x) const
{ return _value < x._value; }
convertible_to_bool operator==(const Wrapped2& x) const
{ return _value == x._value; }
Wrapped2& operator+=(const Wrapped2& x)
{ _value += x._value; return *this; }
@ -123,9 +145,13 @@ namespace
Wrapped2& operator++() { ++_value; return *this; }
Wrapped2& operator--() { --_value; return *this; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
bool operator==(U u) const { return _value == u; }
convertible_to_bool operator<(U u) const
{ return _value < u; }
convertible_to_bool operator>(U u) const
{ return _value > u; }
convertible_to_bool operator==(U u) const
{ return _value == u; }
Wrapped2& operator+=(U u) { _value += u; return *this; }
Wrapped2& operator-=(U u) { _value -= u; return *this; }
Wrapped2& operator*=(U u) { _value *= u; return *this; }
@ -153,7 +179,8 @@ namespace
explicit Wrapped3( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped3& x) const { return _value < x._value; }
convertible_to_bool operator<(const Wrapped3& x) const
{ return _value < x._value; }
private:
T _value;
@ -174,10 +201,13 @@ namespace
explicit Wrapped4( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped4& x) const { return _value < x._value; }
convertible_to_bool operator<(const Wrapped4& x) const
{ return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
convertible_to_bool operator<(U u) const
{ return _value < u; }
convertible_to_bool operator>(U u) const
{ return _value > u; }
private:
T _value;
@ -198,11 +228,18 @@ namespace
Wrapped5(U u) : _value(u) {}
T value() const { return _value; }
bool operator<(const Wrapped5& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
bool operator==(const Wrapped5& u) const { return _value == u._value; }
bool operator==(U u) const { return _value == u; }
convertible_to_bool operator<(const Wrapped5& x) const
{ return _value < x._value; }
convertible_to_bool operator<(U u) const
{ return _value < u; }
convertible_to_bool operator>(U u) const
{ return _value > u; }
convertible_to_bool operator==(const Wrapped5& u) const
{ return _value == u._value; }
convertible_to_bool operator==(U u) const
{ return _value == u; }
Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;}
Wrapped5& operator/=(U u) { _value /= u; return *this;}
Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
@ -221,8 +258,8 @@ namespace
// U must be convertible to T
template <class T, class U>
class Wrapped6
: boost::ordered_euclidian_ring_operators2<Wrapped6<T, U>, U>
, boost::ordered_euclidian_ring_operators1<Wrapped6<T, U> >
: boost::ordered_euclidean_ring_operators2<Wrapped6<T, U>, U>
, boost::ordered_euclidean_ring_operators1<Wrapped6<T, U> >
{
public:
explicit Wrapped6( T v = T() ) : _value(v) {}
@ -231,11 +268,18 @@ namespace
Wrapped6(U u) : _value(u) {}
T value() const { return _value; }
bool operator<(const Wrapped6& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
bool operator==(const Wrapped6& u) const { return _value == u._value; }
bool operator==(U u) const { return _value == u; }
convertible_to_bool operator<(const Wrapped6& x) const
{ return _value < x._value; }
convertible_to_bool operator<(U u) const
{ return _value < u; }
convertible_to_bool operator>(U u) const
{ return _value > u; }
convertible_to_bool operator==(const Wrapped6& u) const
{ return _value == u._value; }
convertible_to_bool operator==(U u) const
{ return _value == u; }
Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;}
Wrapped6& operator%=(U u) { _value %= u; return *this;}
Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;}
@ -276,10 +320,10 @@ namespace
template <class X1, class Y1, class X2, class Y2>
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( (x1 < y1) == (x2 < y2) );
BOOST_CHECK( (x1 <= y1) == (x2 <= y2) );
BOOST_CHECK( (x1 >= y1) == (x2 >= y2) );
BOOST_CHECK( (x1 > y1) == (x2 > y2) );
BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
}
template <class X1, class Y1, class X2, class Y2>
@ -293,8 +337,8 @@ namespace
template <class X1, class Y1, class X2, class Y2>
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( (x1 == y1) == (x2 == y2) );
BOOST_CHECK( (x1 != y1) == (x2 != y2) );
BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
}
template <class X1, class Y1, class X2, class Y2>
@ -614,14 +658,14 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
BOOST_CHECK( i2 == i );
BOOST_CHECK( i1 != i2 );
BOOST_CHECK( i1 < i2 );
BOOST_CHECK( i1 <= i2 );
BOOST_CHECK( i <= i2 );
BOOST_CHECK( i2 > i1 );
BOOST_CHECK( i2 >= i1 );
BOOST_CHECK( i2 >= i );
BOOST_CHECK( static_cast<bool>(i2 == i) );
BOOST_CHECK( static_cast<bool>(i1 != i2) );
BOOST_CHECK( static_cast<bool>(i1 < i2) );
BOOST_CHECK( static_cast<bool>(i1 <= i2) );
BOOST_CHECK( static_cast<bool>(i <= i2) );
BOOST_CHECK( static_cast<bool>(i2 > i1) );
BOOST_CHECK( static_cast<bool>(i2 >= i1) );
BOOST_CHECK( static_cast<bool>(i2 >= i) );
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
@ -653,78 +697,78 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
BOOST_CHECK( j2 == j );
BOOST_CHECK( 2 == j );
BOOST_CHECK( j2 == 2 );
BOOST_CHECK( j == j2 );
BOOST_CHECK( j1 != j2 );
BOOST_CHECK( j1 != 2 );
BOOST_CHECK( 1 != j2 );
BOOST_CHECK( j1 < j2 );
BOOST_CHECK( 1 < j2 );
BOOST_CHECK( j1 < 2 );
BOOST_CHECK( j1 <= j2 );
BOOST_CHECK( 1 <= j2 );
BOOST_CHECK( j1 <= j );
BOOST_CHECK( j <= j2 );
BOOST_CHECK( 2 <= j2 );
BOOST_CHECK( j <= 2 );
BOOST_CHECK( j2 > j1 );
BOOST_CHECK( 2 > j1 );
BOOST_CHECK( j2 > 1 );
BOOST_CHECK( j2 >= j1 );
BOOST_CHECK( 2 >= j1 );
BOOST_CHECK( j2 >= 1 );
BOOST_CHECK( j2 >= j );
BOOST_CHECK( 2 >= j );
BOOST_CHECK( j2 >= 2 );
BOOST_CHECK( static_cast<bool>(j2 == j) );
BOOST_CHECK( static_cast<bool>(2 == j) );
BOOST_CHECK( static_cast<bool>(j2 == 2) );
BOOST_CHECK( static_cast<bool>(j == j2) );
BOOST_CHECK( static_cast<bool>(j1 != j2) );
BOOST_CHECK( static_cast<bool>(j1 != 2) );
BOOST_CHECK( static_cast<bool>(1 != j2) );
BOOST_CHECK( static_cast<bool>(j1 < j2) );
BOOST_CHECK( static_cast<bool>(1 < j2) );
BOOST_CHECK( static_cast<bool>(j1 < 2) );
BOOST_CHECK( static_cast<bool>(j1 <= j2) );
BOOST_CHECK( static_cast<bool>(1 <= j2) );
BOOST_CHECK( static_cast<bool>(j1 <= j) );
BOOST_CHECK( static_cast<bool>(j <= j2) );
BOOST_CHECK( static_cast<bool>(2 <= j2) );
BOOST_CHECK( static_cast<bool>(j <= 2) );
BOOST_CHECK( static_cast<bool>(j2 > j1) );
BOOST_CHECK( static_cast<bool>(2 > j1) );
BOOST_CHECK( static_cast<bool>(j2 > 1) );
BOOST_CHECK( static_cast<bool>(j2 >= j1) );
BOOST_CHECK( static_cast<bool>(2 >= j1) );
BOOST_CHECK( static_cast<bool>(j2 >= 1) );
BOOST_CHECK( static_cast<bool>(j2 >= j) );
BOOST_CHECK( static_cast<bool>(2 >= j) );
BOOST_CHECK( static_cast<bool>(j2 >= 2) );
BOOST_CHECK( (j1 + 2) == 3 );
BOOST_CHECK( (1 + j2) == 3 );
BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
BOOST_CHECK( (j + 2) == 5 );
BOOST_CHECK( (3 + j2) == 5 );
BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
BOOST_CHECK( (j - 1) == 4 );
BOOST_CHECK( static_cast<bool>((j - 1) == 4) );
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
BOOST_CHECK( (j * 2) == 8 );
BOOST_CHECK( (4 * j2) == 8 );
BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
BOOST_CHECK( (j / 2) == 4 );
BOOST_CHECK( static_cast<bool>((j / 2) == 4) );
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
BOOST_CHECK( (j % 3) == 1 );
BOOST_CHECK( static_cast<bool>((j % 3) == 1) );
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
BOOST_CHECK( (1 | j2 | j) == 7 );
BOOST_CHECK( (j1 | 2 | j) == 7 );
BOOST_CHECK( (j1 | j2 | 4) == 7 );
BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
BOOST_CHECK( (7 & j2) == 2 );
BOOST_CHECK( (j & 2) == 2 );
BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
BOOST_CHECK( (3 ^ j1) == 2 );
BOOST_CHECK( (j ^ 1) == 2 );
BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
BOOST_CHECK( (j1 << 2) == 4 );
BOOST_CHECK( (j2 << 1) == 4 );
BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
BOOST_CHECK( (j >> 2) == 1 );
BOOST_CHECK( (j2 >> 1) == 1 );
BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
cout << "Performed tests on MyLong objects.\n";
@ -741,14 +785,14 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
BOOST_CHECK( k2 == k );
BOOST_CHECK( k1 != k2 );
BOOST_CHECK( k1 < k2 );
BOOST_CHECK( k1 <= k2 );
BOOST_CHECK( k <= k2 );
BOOST_CHECK( k2 > k1 );
BOOST_CHECK( k2 >= k1 );
BOOST_CHECK( k2 >= k );
BOOST_CHECK( static_cast<bool>(k2 == k) );
BOOST_CHECK( static_cast<bool>(k1 != k2) );
BOOST_CHECK( static_cast<bool>(k1 < k2) );
BOOST_CHECK( static_cast<bool>(k1 <= k2) );
BOOST_CHECK( static_cast<bool>(k <= k2) );
BOOST_CHECK( static_cast<bool>(k2 > k1) );
BOOST_CHECK( static_cast<bool>(k2 >= k1) );
BOOST_CHECK( static_cast<bool>(k2 >= k) );
cout << "Performed tests on MyChar objects.\n";
@ -764,31 +808,31 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
BOOST_CHECK( l2 == l );
BOOST_CHECK( 2 == l );
BOOST_CHECK( l2 == 2 );
BOOST_CHECK( l == l2 );
BOOST_CHECK( l1 != l2 );
BOOST_CHECK( l1 != 2 );
BOOST_CHECK( 1 != l2 );
BOOST_CHECK( l1 < l2 );
BOOST_CHECK( 1 < l2 );
BOOST_CHECK( l1 < 2 );
BOOST_CHECK( l1 <= l2 );
BOOST_CHECK( 1 <= l2 );
BOOST_CHECK( l1 <= l );
BOOST_CHECK( l <= l2 );
BOOST_CHECK( 2 <= l2 );
BOOST_CHECK( l <= 2 );
BOOST_CHECK( l2 > l1 );
BOOST_CHECK( 2 > l1 );
BOOST_CHECK( l2 > 1 );
BOOST_CHECK( l2 >= l1 );
BOOST_CHECK( 2 >= l1 );
BOOST_CHECK( l2 >= 1 );
BOOST_CHECK( l2 >= l );
BOOST_CHECK( 2 >= l );
BOOST_CHECK( l2 >= 2 );
BOOST_CHECK( static_cast<bool>(l2 == l) );
BOOST_CHECK( static_cast<bool>(2 == l) );
BOOST_CHECK( static_cast<bool>(l2 == 2) );
BOOST_CHECK( static_cast<bool>(l == l2) );
BOOST_CHECK( static_cast<bool>(l1 != l2) );
BOOST_CHECK( static_cast<bool>(l1 != 2) );
BOOST_CHECK( static_cast<bool>(1 != l2) );
BOOST_CHECK( static_cast<bool>(l1 < l2) );
BOOST_CHECK( static_cast<bool>(1 < l2) );
BOOST_CHECK( static_cast<bool>(l1 < 2) );
BOOST_CHECK( static_cast<bool>(l1 <= l2) );
BOOST_CHECK( static_cast<bool>(1 <= l2) );
BOOST_CHECK( static_cast<bool>(l1 <= l) );
BOOST_CHECK( static_cast<bool>(l <= l2) );
BOOST_CHECK( static_cast<bool>(2 <= l2) );
BOOST_CHECK( static_cast<bool>(l <= 2) );
BOOST_CHECK( static_cast<bool>(l2 > l1) );
BOOST_CHECK( static_cast<bool>(2 > l1) );
BOOST_CHECK( static_cast<bool>(l2 > 1) );
BOOST_CHECK( static_cast<bool>(l2 >= l1) );
BOOST_CHECK( static_cast<bool>(2 >= l1) );
BOOST_CHECK( static_cast<bool>(l2 >= 1) );
BOOST_CHECK( static_cast<bool>(l2 >= l) );
BOOST_CHECK( static_cast<bool>(2 >= l) );
BOOST_CHECK( static_cast<bool>(l2 >= 2) );
cout << "Performed tests on MyShort objects.\n";
@ -807,37 +851,37 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
BOOST_CHECK( di2 == di );
BOOST_CHECK( 2 == di );
BOOST_CHECK( di == 2 );
BOOST_CHECK( di1 < di2 );
BOOST_CHECK( 1 < di2 );
BOOST_CHECK( di1 <= di2 );
BOOST_CHECK( 1 <= di2 );
BOOST_CHECK( di2 > di1 );
BOOST_CHECK( di2 > 1 );
BOOST_CHECK( di2 >= di1 );
BOOST_CHECK( di2 >= 1 );
BOOST_CHECK( di1 / di2 == half );
BOOST_CHECK( di1 / 2 == half );
BOOST_CHECK( 1 / di2 == half );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=2) == half) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=di2) == half) );
BOOST_CHECK( di1 * di2 == di2 );
BOOST_CHECK( di1 * 2 == di2 );
BOOST_CHECK( 1 * di2 == di2 );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=2) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=di2) == di2) );
BOOST_CHECK( di2 - di1 == di1 );
BOOST_CHECK( di2 - 1 == di1 );
BOOST_CHECK( 2 - di1 == di1 );
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=1) == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=di1) == di1) );
BOOST_CHECK( di1 + di1 == di2 );
BOOST_CHECK( di1 + 1 == di2 );
BOOST_CHECK( 1 + di1 == di2 );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=di1) == di2) );
BOOST_CHECK( static_cast<bool>(di2 == di) );
BOOST_CHECK( static_cast<bool>(2 == di) );
BOOST_CHECK( static_cast<bool>(di == 2) );
BOOST_CHECK( static_cast<bool>(di1 < di2) );
BOOST_CHECK( static_cast<bool>(1 < di2) );
BOOST_CHECK( static_cast<bool>(di1 <= di2) );
BOOST_CHECK( static_cast<bool>(1 <= di2) );
BOOST_CHECK( static_cast<bool>(di2 > di1) );
BOOST_CHECK( static_cast<bool>(di2 > 1) );
BOOST_CHECK( static_cast<bool>(di2 >= di1) );
BOOST_CHECK( static_cast<bool>(di2 >= 1) );
BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
cout << "Performed tests on MyDoubleInt objects.\n";
@ -854,42 +898,42 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
BOOST_CHECK( li2 == li );
BOOST_CHECK( 2 == li );
BOOST_CHECK( li == 2 );
BOOST_CHECK( li1 < li2 );
BOOST_CHECK( 1 < li2 );
BOOST_CHECK( li1 <= li2 );
BOOST_CHECK( 1 <= li2 );
BOOST_CHECK( li2 > li1 );
BOOST_CHECK( li2 > 1 );
BOOST_CHECK( li2 >= li1 );
BOOST_CHECK( li2 >= 1 );
BOOST_CHECK( li1 % li2 == li1 );
BOOST_CHECK( li1 % 2 == li1 );
BOOST_CHECK( 1 % li2 == li1 );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=2) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=li2) == li1) );
BOOST_CHECK( li1 / li2 == 0 );
BOOST_CHECK( li1 / 2 == 0 );
BOOST_CHECK( 1 / li2 == 0 );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=2) == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=li2) == 0) );
BOOST_CHECK( li1 * li2 == li2 );
BOOST_CHECK( li1 * 2 == li2 );
BOOST_CHECK( 1 * li2 == li2 );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=2) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=li2) == li2) );
BOOST_CHECK( li2 - li1 == li1 );
BOOST_CHECK( li2 - 1 == li1 );
BOOST_CHECK( 2 - li1 == li1 );
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=1) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=li1) == li1) );
BOOST_CHECK( li1 + li1 == li2 );
BOOST_CHECK( li1 + 1 == li2 );
BOOST_CHECK( 1 + li1 == li2 );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) );
BOOST_CHECK( static_cast<bool>(li2 == li) );
BOOST_CHECK( static_cast<bool>(2 == li) );
BOOST_CHECK( static_cast<bool>(li == 2) );
BOOST_CHECK( static_cast<bool>(li1 < li2) );
BOOST_CHECK( static_cast<bool>(1 < li2) );
BOOST_CHECK( static_cast<bool>(li1 <= li2) );
BOOST_CHECK( static_cast<bool>(1 <= li2) );
BOOST_CHECK( static_cast<bool>(li2 > li1) );
BOOST_CHECK( static_cast<bool>(li2 > 1) );
BOOST_CHECK( static_cast<bool>(li2 >= li1) );
BOOST_CHECK( static_cast<bool>(li2 >= 1) );
BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
cout << "Performed tests on MyLongInt objects.\n";

View File

@ -68,11 +68,54 @@ struct ref_wrapper
}
};
struct copy_counter {
static int count_;
copy_counter(copy_counter const& /*other*/) {
++count_;
}
copy_counter() {}
static void reset() { count_ = 0; }
static int count() { return copy_counter::count_; }
};
int copy_counter::count_ = 0;
} // namespace unnamed
template <class T>
void do_unwrap(T t) {
/* typename unwrap_reference<T>::type& lt = */
unwrap_ref(t);
}
void unwrap_test() {
int i = 3;
const int ci = 2;
do_unwrap(i);
do_unwrap(ci);
do_unwrap(ref(i));
do_unwrap(cref(ci));
do_unwrap(ref(ci));
copy_counter cc;
BOOST_CHECK(cc.count() == 0);
do_unwrap(cc);
do_unwrap(ref(cc));
do_unwrap(cref(cc));
BOOST_CHECK(cc.count() == 1);
BOOST_CHECK(unwrap_ref(ref(cc)).count() == 1);
}
int test_main(int, char * [])
{
ref_wrapper<int>::test(1);
ref_wrapper<int const>::test(1);
unwrap_test();
return 0;
}

98
swap.html Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Boost: Swap Documentation</title>
</head>
<body>
<!-- Page header -->
<h2>
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/>
Header &lt;<a href="../../boost/swap.hpp">boost/swap.hpp</a>&gt;
</h2>
<h1>Swap</h1>
<p>
<tt>template&lt;class T&gt; void swap(T&amp; <em>left</em>, T&amp; <em>right</em>);</tt>
</p>
<!-- 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>
<!-- Rationale -->
<h2>Rationale</h2>
<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 <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> 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 -->
<h2>Exception Safety</h2>
<p>
<tt>boost::swap</tt> provides the same exception guarantee as the underlying swap function used, with one exception; for an array of type <tt>T[n]</tt>, where <tt>n > 1</tt> and the underlying swap function for <tt>T</tt> provides the strong exception guarantee, <tt>boost::swap</tt> provides only the basic exception guarantee.
</p>
<!-- Requirements -->
<h2>Requirements</h2>
<p>Either:</p>
<ul>
<li>T must be assignable</li>
<li>T must be copy constructible</li>
</ul>
<p>Or:</p>
<ul>
<li>A function with the signature <tt>swap(T&amp;,T&amp;)</tt> is available via argument dependent lookup</li>
</ul>
<p>Or:</p>
<ul>
<li>A template specialization of <tt>std::swap</tt> exists for T</li>
</ul>
<p>Or:</p>
<ul>
<li>T is a built-in array of swappable elements</li>
</ul>
<!-- Portability -->
<h2>Portability</h2>
<p>
Several older compilers do not support argument dependent lookup &#x2012; on these compilers <tt>boost::swap</tt> will call <tt>std::swap</tt>, ignoring any specialized swap functions that could be found as a result of argument dependent lookup.
</p>
<!-- Credits -->
<h2>Credits</h2>
<ul>
<li>
<em>Niels Dekker</em> - for implementing and documenting support for built-in arrays
</li>
<li>
<em><a href="mailto:Joseph.Gauterin@googlemail.com">Joseph Gauterin</a></em> - for the initial idea, implementation, tests, and documentation
</li>
<li>
<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-defects.html#809">LWG Defect Report 809 (std::swap should be overloaded for array types)</a></p>
<!-- Copyright info -->
<hr/>
<p>Revised: 08 September 2009</p>
<p>
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 &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)
</p>
</body>
</html>

37
swap/test/Jamfile.v2 Normal file
View File

@ -0,0 +1,37 @@
# Copyright (c) 2007, 2008 Joseph Gauterin
#
# 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)
# bring in rules for testing
import testing ;
test-suite utility/swap
:
[ compile root_header_1.cpp ]
[ compile root_header_2.cpp ]
[ compile lib_header_1.cpp ]
[ compile lib_header_2.cpp ]
[ compile mixed_headers_1.cpp ]
[ compile mixed_headers_2.cpp ]
[ run primitive.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_std.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_boost_and_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_bitset.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_dateorder.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_string.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_typeinfo_ptr.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_vector_of_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ 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 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 ]
;

View File

@ -0,0 +1,69 @@
// 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 first_dimension = 3;
const std::size_t second_dimension = 4;
const std::size_t number_of_elements = first_dimension * second_dimension;
swap_test_class array1[first_dimension][second_dimension];
swap_test_class array2[first_dimension][second_dimension];
swap_test_class* const ptr1 = array1[0];
swap_test_class* const ptr2 = array2[0];
for (std::size_t i = 0; i < number_of_elements; ++i)
{
ptr1[i].set_data( static_cast<int>(i) );
ptr2[i].set_data( 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].get_data(), static_cast<int>(i + number_of_elements) );
BOOST_CHECK_EQUAL(ptr2[i].get_data(), static_cast<int>(i) );
}
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
return 0;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View File

@ -0,0 +1,10 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap header compiles as a standalone translation unit
#include <boost/utility/swap.hpp>

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap header include guards work correctly
#include <boost/utility/swap.hpp>
#include <boost/utility/swap.hpp>

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap headers work when both are included
#include <boost/swap.hpp>
#include <boost/utility/swap.hpp>

View File

@ -0,0 +1,12 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap headers work when both are included
#include <boost/utility/swap.hpp>
#include <boost/swap.hpp>

View File

@ -0,0 +1,44 @@
// 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)
// boost::swap internally does an unqualified function call to swap.
// This could have led to ambiguity or infinite recursion, when the
// objects to be swapped would themselves be from the boost namespace.
// If so, boost::swap itself might be found by argument dependent lookup.
// The implementation of boost::swap resolves this issue by giving
// boost::swap two template argumetns, thereby making it less specialized
// than std::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
int test_main(int, char*[])
{
const boost::swap_test_class initial_value1(1);
const boost::swap_test_class initial_value2(2);
boost::swap_test_class object1 = initial_value1;
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),0);
BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),3);
return 0;
}

23
swap/test/primitive.cpp Normal file
View File

@ -0,0 +1,23 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
int test_main(int, char*[])
{
int object1 = 1;
int object2 = 2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,2);
BOOST_CHECK_EQUAL(object2,1);
return 0;
}

View File

@ -0,0 +1,10 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap header compiles as a standalone translation unit
#include <boost/swap.hpp>

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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 that the swap header include guards work correctly
#include <boost/swap.hpp>
#include <boost/swap.hpp>

View File

@ -0,0 +1,45 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const boost::swap_test_class initial_value1(1);
const boost::swap_test_class initial_value2(2);
boost::swap_test_class object1 = initial_value1;
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,64 @@
// 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 whether instances of a class from a namespace other than boost are
// properly swapped, when both boost and the other namespace have a custom
// swap function for that class. Note that it shouldn't be necessary for a class
// in an other namespace to have a custom swap function in boost, because the
// boost::swap utility should find the swap function in the other namespace, by
// argument dependent lookup (ADL). Unfortunately ADL isn't fully implemented
// by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1, and
// Borland 5.9.3. Users of those compilers might consider adding a swap overload
// to the boost namespace.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(::other::swap_test_class& left, ::other::swap_test_class& right)
{
left.swap(right);
}
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const other::swap_test_class initial_value1(1);
const other::swap_test_class initial_value2(2);
other::swap_test_class object1 = initial_value1;
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,39 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in gloabl namespace
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
int test_main(int, char*[])
{
const swap_test_class initial_value1(1);
const swap_test_class initial_value2(2);
swap_test_class object1 = initial_value1;
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,45 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const other::swap_test_class initial_value1(1);
const other::swap_test_class initial_value2(2);
other::swap_test_class object1 = initial_value1;
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,44 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in namespace std
namespace std
{
template <>
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const swap_test_class initial_value1(1);
const swap_test_class initial_value2(2);
swap_test_class object1 = initial_value1;
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

33
swap/test/std_bitset.cpp Normal file
View File

@ -0,0 +1,33 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping std::bitset<T> objects by means of boost::swap.
// Unlike most other Standard C++ Library template classes,
// std::bitset<T> does not have its own std::swap overload.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <bitset>
int test_main(int, char*[])
{
typedef std::bitset<8> bitset_type;
const bitset_type initial_value1 = 1;
const bitset_type initial_value2 = 2;
bitset_type object1 = initial_value1;
bitset_type object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

View File

@ -0,0 +1,32 @@
// 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 std::time_base::dateorder objects by means of boost::swap.
// std::time_base::dateorder is an enumerated type. It does not have an
// std::swap overload or template specialization.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <locale>
int test_main(int, char*[])
{
const std::time_base::dateorder initial_value1 = std::time_base::dmy;
const std::time_base::dateorder initial_value2 = std::time_base::mdy;
std::time_base::dateorder object1 = initial_value1;
std::time_base::dateorder object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

31
swap/test/std_string.cpp Normal file
View File

@ -0,0 +1,31 @@
// 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 std::string objects by means of boost::swap.
// std::string has its own std::swap overload.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <string>
int test_main(int, char*[])
{
const std::string initial_value1 = "one";
const std::string initial_value2 = "two";
std::string object1 = initial_value1;
std::string object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

View File

@ -0,0 +1,32 @@
// 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 std::type_info pointers by means of boost::swap.
// There is no std::swap overload or template specialization
// for std::type_info pointers.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <typeinfo>
int test_main(int, char*[])
{
const std::type_info * const initial_value1 = 0;
const std::type_info * const initial_value2 = &typeid(double);
const std::type_info * ptr1 = initial_value1;
const std::type_info * ptr2 = initial_value2;
boost::swap(ptr1,ptr2);
BOOST_CHECK_EQUAL(ptr1,initial_value2);
BOOST_CHECK_EQUAL(ptr2,initial_value1);
return 0;
}

View File

@ -0,0 +1,60 @@
// 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 std::vector objects by means of boost::swap,
// having boost::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
typedef boost::swap_test_class swap_test_class_type;
typedef std::vector<swap_test_class_type> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class_type(1));
const vector_type initial_value2(initial_size2, swap_test_class_type(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class_type::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,53 @@
// 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 std::vector objects by means of boost::swap,
// having ::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in the global namespace
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
int test_main(int, char*[])
{
typedef std::vector<swap_test_class> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class(1));
const vector_type initial_value2(initial_size2, swap_test_class(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,60 @@
// 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 std::vector objects by means of boost::swap,
// having other::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
typedef other::swap_test_class swap_test_class_type;
typedef std::vector<swap_test_class_type> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class_type(1));
const vector_type initial_value2(initial_size2, swap_test_class_type(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class_type::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0);
return 0;
}

View File

@ -0,0 +1,114 @@
// Copyright (c) 2007-2008 Joseph Gauterin
//
// 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 class used by the Boost.Swap tests
#ifndef BOOST_UTILITY_SWAP_TEST_CLASS_HPP
#define BOOST_UTILITY_SWAP_TEST_CLASS_HPP
class swap_test_class
{
int m_data;
public:
explicit swap_test_class(int arg = 0)
:
m_data(arg)
{
++constructCount();
}
~swap_test_class()
{
++destructCount();
}
swap_test_class(const swap_test_class& arg)
:
m_data(arg.m_data)
{
++copyCount();
++destructCount();
}
swap_test_class& operator=(const swap_test_class& arg)
{
m_data = arg.m_data;
++copyCount();
return *this;
}
void swap(swap_test_class& other)
{
const int temp = m_data;
m_data = other.m_data;
other.m_data = temp;
++swapCount();
}
int get_data() const
{
return m_data;
}
void set_data(int arg)
{
m_data = arg;
}
static unsigned int swap_count(){ return swapCount(); }
static unsigned int copy_count(){ return copyCount(); }
static unsigned int construct_count(){ return constructCount(); }
static unsigned int destruct_count(){ return destructCount(); }
static void reset()
{
swapCount() = 0;
copyCount() = 0;
constructCount() = 0;
destructCount() = 0;
}
private:
static unsigned int& swapCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& copyCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& constructCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& destructCount()
{
static unsigned int value = 0;
return value;
}
};
inline bool operator==(const swap_test_class & lhs, const swap_test_class & rhs)
{
return lhs.get_data() == rhs.get_data();
}
inline bool operator!=(const swap_test_class & lhs, const swap_test_class & rhs)
{
return !(lhs == rhs);
}
#endif

View File

@ -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
View File

View File

@ -5,41 +5,109 @@
// 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>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct int_result_type { typedef int result_type; };
struct int_result_type
{
typedef int result_type;
result_type operator()(float);
};
struct int_result_of
{
template<typename F> struct result { typedef int type; };
result<int_result_of(double)>::type operator()(double);
result<const int_result_of(double)>::type operator()(double) const;
result<int_result_of()>::type operator()();
result<volatile int_result_of()>::type operator()() volatile;
};
struct int_result_type_and_float_result_of
struct int_result_type_and_float_result_of_and_char_return
{
typedef int result_type;
template<typename F> struct result { typedef float type; };
char operator()(char);
};
template<typename T>
struct int_result_type_template { typedef int result_type; };
struct int_result_type_template
{
typedef int result_type;
result_type operator()(float);
};
template<typename T>
struct int_result_of_template
{
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef int type; };
typename result<int_result_of_template<T>(double)>::type operator()(double);
typename result<const int_result_of_template<T>(double)>::type operator()(double) const;
typename result<int_result_of_template<T>(double)>::type operator()();
typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile;
};
template<typename T>
struct int_result_type_and_float_result_of_template
struct int_result_type_and_float_result_of_and_char_return_template
{
typedef int result_type;
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef float type; };
char operator()(char);
};
struct result_of_member_function_template
{
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef That type; };
template<class T> typename result<result_of_member_function_template(T)>::type operator()(T);
template<typename This, typename That> struct result<const This(That)> { typedef const That type; };
template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const;
template<typename This, typename That> struct result<volatile This(That)> { typedef volatile That type; };
template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile;
template<typename This, typename That> struct result<const volatile This(That)> { typedef const volatile That type; };
template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile;
template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; };
template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T);
template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; };
template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T);
template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; };
template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T);
template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; };
template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T);
};
struct no_result_type_or_result_of
{
int operator()(double);
short operator()(double) const;
unsigned int operator()();
unsigned short operator()() volatile;
const unsigned short operator()() const volatile;
};
template<typename T>
struct no_result_type_or_result_of_template
{
int operator()(double);
short operator()(double) const;
unsigned int operator()();
unsigned short operator()() volatile;
const unsigned short operator()() const volatile;
};
struct X {};
@ -60,16 +128,52 @@ int main()
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
// Prior to decltype, result_of could not deduce the return type
// nullary function objects unless they exposed a result_type.
#if !defined(BOOST_NO_DECLTYPE)
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));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value));
#else
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_template<void>(char)>::type, int>::value));
#endif
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
// Prior to decltype, result_of ignored a nested result<> if
// result_type was defined. After decltype, result_of deduces the
// actual return type of the function object, ignoring both
// result<> and result_type.
#if !defined(BOOST_NO_DECLTYPE)
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
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
#endif
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
@ -81,5 +185,54 @@ 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));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
typedef int (*pf_t)(int);
BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
#if !defined(BOOST_NO_DECLTYPE)
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));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of(void)>::type, unsigned short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of(void)>::type, const unsigned short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(void)>::type, unsigned int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value));
#endif
return 0;
}

View File

@ -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">&nbsp;</td>
</tr>
</table>
<p>
The header <STRONG>&lt;boost/throw_exception.hpp&gt;</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 &amp; e); // user defined
#else
template&lt;class E&gt; void throw_exception(E const &amp; 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>.&nbsp;<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>

View File

@ -33,6 +33,7 @@
<ul>
<li><a href="#val_init"><code>template class value_initialized&lt;T&gt;</code></a></li>
<li><a href="#initialized"><code>template class initialized&lt;T&gt;</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&lt;T&gt;</code></a></h2>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&amp;() const { return x ; }<br> T&amp; data() const { return x ; }<br><br> private :<br> <i>unspecified</i> x ;<br>} ;<br><br>template&lt;class T&gt;<br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )<br>{<br> return x.data() ;<br>}<br><br>template&lt;class T&gt;<br>T&amp; get ( value_initialized&lt;T&gt;&amp; x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{
<br> public :
<br> value_initialized() : x() {}
<br> operator T const &amp;() const { return x ; }
<br> operator T&amp;() { return x ; }
<br> T const &amp;data() const { return x ; }
<br> T&amp; data() { return x ; }
<br> void swap( value_initialized&lt;T&gt;&amp; );
<br>
<br> private :
<br> <i>unspecified</i> x ;
<br>} ;
<br>
<br>template&lt;class T&gt;
<br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )
<br>{
<br> return x.data() ;
<br>}
<br>
<br>template&lt;class T&gt;
<br>T&amp; get ( value_initialized&lt;T&gt;&amp; 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&amp;'</code> whose wrapped object (data member of type <code>T</code>)
@ -271,47 +332,95 @@ its internal data, prior to constructing the object that it contains.
<code>T&amp;</code>, the member function <code>data()</code>, or the
non-member function <code>get()</code>: </p>
<pre>void watch(int);<br>value_initialized&lt;int&gt; x;<br><br>watch(x) ; // operator T&amp; used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
<pre>void watch(int);<br>value_initialized&lt;int&gt; x;
<br><br>watch(x) ; // operator T&amp; 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
objects cannot:</p>
<p>When <code>T</code> is a <em>Swappable</em> type, <code>value_initialized&lt;T&gt;</code>
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&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
<pre>value_initialized&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK
<br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(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&lt;int&gt; const x ;<br>foo(x);<br></pre>
<pre>value_initialized&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; available even though x_c is itself const.
<br>xr = 2 ; </pre>
<p>But notice that this conversion operator is to <code>T&amp;</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&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; 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&amp;() ;<br> operator int const&amp;() 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&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
<h2><a name="initialized"><code>template class initialized&lt;T&gt;</code></a></h2>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class initialized<br>{
<br> public :
<br> initialized() : x() {}
<br> explicit initialized(T const &amp; arg) : x(arg) {}
<br> operator T const &amp;() const;
<br> operator T&amp;();
<br> T const &amp;data() const;
<br> T&amp; data();
<br> void swap( value_initialized&lt;T&gt;&amp; );
<br>
<br> private :
<br> <i>unspecified</i> x ;
<br>} ;
<br>
<br>template&lt;class T&gt;
<br>T const&amp; get ( initialized&lt;T&gt; const&amp; x );
<br>
<br>template&lt;class T&gt;
<br>T&amp; get ( initialized&lt;T&gt;&amp; x );
<br>
<br>} // namespace boost
<br></pre>
The template class <code>boost::initialized&lt;T&gt;</code> supports both value-initialization
and direct-initialization, so its interface is a superset of the interface
of <code>value_initialized&lt;T&gt;</code>: Its default-constructor
value-initializes the wrapped object just like the default-constructor of
<code>value_initialized&lt;T&gt;</code>, but <code>boost::initialized&lt;T&gt;</code>
also offers an extra <code>explicit</code>
constructor, which direct-initializes the wrapped object by the specified value.
<p>
<code>initialized&lt;T&gt;</code> is especially useful when the wrapped
object must be either value-initialized or direct-initialized, depending on
runtime conditions. For example, <code>initialized&lt;T&gt;</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&lt;T&gt;</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>
@ -371,6 +480,9 @@ Special thanks to Bj&ouml;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>,
@ -379,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
</p>
<hr>
<p>Revised 23 May 2008</p>
<p>Revised 30 May 2010</p>
<p>&copy; Copyright Fernando Cacciola, 2002, 2008.</p>
<p>&copy; 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>

View File

@ -9,6 +9,7 @@
// 21 Ago 2002 (Created) Fernando Cacciola
// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker
// 21 Ago 2008 (Added swap test) Niels Dekker
#include <cstring> // For memcmp.
#include <iostream>
@ -28,9 +29,9 @@
//
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 << ')' ; }
@ -181,6 +182,35 @@ struct CopyFunctionCallTester
};
//
// A struct that allows testing whether its customized swap function is called.
//
struct SwapFunctionCallTester
{
bool is_custom_swap_called;
int data;
SwapFunctionCallTester()
: is_custom_swap_called(false), data(0) {}
SwapFunctionCallTester(const SwapFunctionCallTester & arg)
: is_custom_swap_called(false), data(arg.data) {}
void swap(SwapFunctionCallTester & arg)
{
std::swap(data, arg.data);
is_custom_swap_called = true;
arg.is_custom_swap_called = true;
}
};
void swap(SwapFunctionCallTester & lhs, SwapFunctionCallTester & rhs)
{
lhs.swap(rhs);
}
template<class T>
void check_initialized_value ( T const& y )
{
@ -196,7 +226,7 @@ void check_initialized_value( NonPOD const& )
// and this type (NonPOD), because the following statement
// won't compile on this particular compiler version:
// NonPOD initializedValue = boost::initialized_value() ;
//
//
// This is caused by a compiler bug, that is fixed with a newer version
// of the Borland compiler. The Release Notes for Delphi(R) 2007 for
// Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
@ -230,7 +260,7 @@ bool test ( T const& y, T const& 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 ;
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
x_c_ref = z ;
BOOST_CHECK ( x_c == z ) ;
@ -261,7 +291,7 @@ int test_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( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
NonPOD NonPOD_object( std::string("NonPOD_object") );
@ -323,9 +353,20 @@ int test_main(int, char **)
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
BOOST_CHECK ( 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 );
return 0;
}
unsigned int expected_failures = 0;

View 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
}