Compare commits

..

48 Commits

Author SHA1 Message Date
Daniel James
9deb4dd823 Create a branch for inspect fixes.
[SVN r61439]
2010-04-20 21:11:27 +00:00
Eric Niebler
e3c982287a add tr1_result_of that always behaves as TR1 specifies, fix Boost.TR1's result_of to use tr1_result_of
[SVN r61248]
2010-04-13 15:01:11 +00:00
Daniel James
82e1111bb8 Revert [60052], as it causes other libraries to break.
[SVN r61097]
2010-04-06 07:56:54 +00:00
Niels Dekker
9339b32178 Updated copyright notice.
[SVN r61075]
2010-04-05 19:08:01 +00:00
Niels Dekker
3770221507 Hopefully fixed #3984 (std::bitset constructor issue). Tested by Juergen Hunold on msvc-10.0, msvc-9.0, and gcc-4.4. See thread starting at http://lists.boost.org/Archives/boost/2010/03/162690.php
[SVN r60331]
2010-03-07 21:42:22 +00:00
Daniel James
e6cb3a77ee Fix a couple of comments.
[SVN r60294]
2010-03-07 13:11:10 +00:00
Daniel James
bbccfbbab4 Remove use of deprecated macro in result_of test.
[SVN r60293]
2010-03-07 13:10:54 +00:00
Daniel James
74a6a693d3 Remove use of deprecated config macro in result_of.
[SVN r60052]
2010-03-01 19:39:52 +00:00
Dave Abrahams
bf713ad47a Revert unintentional reference to "noncopyable_adl_barrier" test that's not checked in.
[SVN r59332]
2010-01-28 14:41:16 +00:00
Dave Abrahams
76b17c497b Support different MS calling conventions, thanks to Nicolas Lelong.
Closes #3833.


[SVN r59247]
2010-01-24 02:08:46 +00:00
Emil Dotchevski
3de5974419 Suppressing warnings. Please report any problems (may have broken something!)
[SVN r58072]
2009-12-01 02:16:50 +00:00
John Maddock
7eb1536590 Suppress/fix some msvc and gcc compiler warnings.
[SVN r57494]
2009-11-08 18:53:59 +00:00
Troy D. Straszheim
9339431e03 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Niels Dekker
f2349baf7d Updated value_init documentation, because the fix of #2548 was not yet included with Boost release 1.40.0.
[SVN r56544]
2009-10-03 09:18:26 +00:00
Niels Dekker
8745ca628a Updated revision date of Boost Swap documentation
[SVN r56108]
2009-09-08 17:07:13 +00:00
Niels Dekker
ba61e9d796 Mentioned swap.hpp header, as requested by Thorsten Ottosen <http://lists.boost.org/Archives/boost/2009/06/153477.php> and David Abrahams <http://lists.boost.org/Archives/boost/2009/09/156064.php>
[SVN r56107]
2009-09-08 16:54:54 +00:00
Troy D. Straszheim
afe74fffbc Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Niels Dekker
09a0137016 Reverted value_init revision [54502], intel_9_value_init_conversion-operator.patch from ticket #2548, as it only increased the number of compile errors at the regression page, and Fernando Cacciola also suggested me to leave it broken (without the patch), for this specific (old) compiler version.
[SVN r54832]
2009-07-09 08:06:19 +00:00
Emil Dotchevski
a1d3ec6c53 Documentation update
[SVN r54828]
2009-07-09 03:51:30 +00:00
Emil Dotchevski
5be3004e6c Added commonly used error_info typedefs.
Added boost/exception/all.hpp.
Removed tabs from source files.

[SVN r54825]
2009-07-08 23:44:28 +00:00
Niels Dekker
d387905150 Updated documentation of value_initialized, according to a remark by Daniel James at ticket #2548
[SVN r54503]
2009-06-29 18:04:24 +00:00
Niels Dekker
b514e40733 Worked around Intel 9 specific ambiguity w.r.t. value_initialized conversion operators, by applying intel_9_value_init_conversion-operator.patch, as discussed w/ Daniel James at ticket #2548
[SVN r54502]
2009-06-29 17:53:33 +00:00
Jeremiah Willcock
b02677375f Fixed most tab and min/max issues from trunk inspection report
[SVN r53141]
2009-05-20 19:19:00 +00:00
Steven Watanabe
61a6015b5a Replace aFactoty with aFactory. Fixes #3019
[SVN r53060]
2009-05-17 00:06:34 +00:00
Daniel James
682032a340 Use a local copy of the valid HTML 4.01 icon.
[SVN r53048]
2009-05-16 14:23:59 +00:00
Eric Niebler
67afd7e315 eliminate noisy warning on msvc, fixes #2993
[SVN r52837]
2009-05-07 17:47:08 +00:00
Daniel Frey
75cf20cace primary operand type must be class type, see ticket #2938
[SVN r52463]
2009-04-18 09:06:31 +00:00
Peter Dimov
91385ac627 Another try at the Sun workaround.
[SVN r52010]
2009-03-27 12:50:09 +00:00
Peter Dimov
61e9b93f7c Try the Sun workaround with int instead of size_t.
[SVN r51986]
2009-03-26 13:05:05 +00:00
Peter Dimov
d97b303777 Try to fix array addressof failures on Sun C++.
[SVN r51977]
2009-03-26 00:06:47 +00:00
Peter Dimov
3900e8ece4 Disable new addressof code for all Borland versions. Refs #2878.
[SVN r51891]
2009-03-21 20:20:37 +00:00
Peter Dimov
e27fc4a853 Attempt to fix addressof in trunk to handle classes with conversion operators. Refs #2878.
[SVN r51872]
2009-03-20 17:14:00 +00:00
Peter Dimov
f7aa9a8935 Refs #2128 (fixed in trunk.)
[SVN r51512]
2009-03-01 17:04:14 +00:00
Niels Dekker
0af1959b30 Updated value_initialized documentation and test following changeset [51355].
[SVN r51356]
2009-02-20 20:35:34 +00:00
Niels Dekker
5f0cf4f5de Fixed const issue of value_initialized according to ticket #2548. See also http://lists.boost.org/Archives/boost/2009/02/148489.php
[SVN r51355]
2009-02-20 20:28:54 +00:00
Emil Dotchevski
0282c8a141 added #error in headers incompatible with BOOST_NO_EXCEPTIONS
[SVN r50887]
2009-01-30 00:06:01 +00:00
Emil Dotchevski
6725719bd9 This html was outdated; changed to forward to throw_exception.html documentation from Boost Exception
[SVN r50879]
2009-01-29 19:13:08 +00:00
Niels Dekker
97e11b024e [utility/swap] Distinguished between testing array-of-array-of-class and array-of-array-of-int, as the latter appears to succeed on CodeGear 6.10 while the former does not.
[SVN r49954]
2008-11-27 11:14:52 +00:00
Niels Dekker
118e473a3d [utility/swap] Added comment to various array swapping tests, added member typedef to swap_test_template, to make the test more realistic.
[SVN r49953]
2008-11-27 11:08:05 +00:00
Niels Dekker
d4b6193f94 Replaced swap/test/swap_arrays by more specific tests: array_of_array, array_of_class, and array_of_int.
[SVN r49916]
2008-11-24 17:41:15 +00:00
Niels Dekker
d420c98a53 Added array_of_template test, testing the boost::swap utility on an array of objects of a template class.
[SVN r49862]
2008-11-21 21:28:47 +00:00
Daniel James
d153ab4daa Fix a typo.
[SVN r49811]
2008-11-16 23:10:00 +00:00
Niels Dekker
561f83b991 Updated swap.html because LWG issue 809 is now accepted as a defect. Fixed some HTML formatting.
[SVN r49771]
2008-11-15 15:07:42 +00:00
Michael A. Jackson
57124703f9 Fixing include path to compile with modularized source tree.
[SVN r49685]
2008-11-11 17:22:34 +00:00
Michael A. Jackson
53f6d10652 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson
ebe853ff2f Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Niels Dekker
487a5c1ea5 Swap documentation: fixed a misspelling of the name of Steven Watanabe.
[SVN r49416]
2008-10-21 09:55:54 +00:00
Daniel James
c4338b1ce8 Clean up some link errors.
[SVN r48987]
2008-09-28 12:21:39 +00:00
39 changed files with 1244 additions and 425 deletions

View File

@@ -85,7 +85,7 @@
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <p>Revised

View File

@@ -509,7 +509,7 @@ Returns the largest size that this Collection can ever have. <A href="#8">[8]</A
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <p>Revised

View File

@@ -160,7 +160,7 @@ t.~T()
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <p>Revised

View File

@@ -185,7 +185,7 @@
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <p>Revised

View File

@@ -70,7 +70,7 @@
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <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 else
{ {
return a.second->before( *b.second ); return a.second->before( *b.second ) != 0;
} }
} }
} }

View File

@@ -11,6 +11,10 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #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 Note: This file tests every single valid bit-grouping on its own, and some
random combinations of bit-groupings. random combinations of bit-groupings.

View File

@@ -21,6 +21,10 @@
#include <libs/type_traits/test/test.hpp> #include <libs/type_traits/test/test.hpp>
#include <libs/type_traits/test/check_type.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 // a way prevent warnings for unused variables
template<class T> inline void unused_variable(const T&) {} template<class T> inline void unused_variable(const T&) {}
@@ -52,7 +56,8 @@ struct contained
const_reference const_get()const { return v_; } const_reference const_get()const { return v_; }
// pass value: // pass value:
void call(param_type){} void call(param_type){}
private:
contained& operator=(const contained&);
}; };
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@@ -77,6 +82,8 @@ struct contained<T[N]>
reference get() { return v_; } reference get() { return v_; }
const_reference const_get()const { return v_; } const_reference const_get()const { return v_; }
void call(param_type){} void call(param_type){}
private:
contained& operator=(const contained&);
}; };
#endif #endif
@@ -197,7 +204,7 @@ struct comparible_UDT
bool operator == (const comparible_UDT& v){ return v.i_ == i_; } bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
}; };
int main(int argc, char *argv[ ]) int main()
{ {
call_traits_checker<comparible_UDT> c1; call_traits_checker<comparible_UDT> c1;
comparible_UDT u; comparible_UDT u;

View File

@@ -146,7 +146,7 @@ int main()
<hr> <hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= <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> height="31" width="88"></a></p>
<p>Revised <p>Revised

View File

@@ -99,7 +99,7 @@ directly to the container:</p>
<H2><A NAME="framework"></A>Framework</H2> <H2><A NAME="framework"></A>Framework</H2>
<p> <p>
This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring 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> 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). 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 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 <pre>struct C
{ {
template&lt;class InPlaceFactory&gt; template&lt;class InPlaceFactory&gt;
C ( InPlaceFactory const& aFactoty ) C ( InPlaceFactory const& aFactory )
: :
contained_ ( uninitialized_storage() ) 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 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> <A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P>
</BODY> </BODY>
</HTML> </HTML>

View File

@@ -6,12 +6,6 @@
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 #ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
#define UUID_1D94A7C6054E11DB9804B622A1EF5492 #define UUID_1D94A7C6054E11DB9804B622A1EF5492
#include <boost/exception/diagnostic_information.hpp> #error The header <boost/exception.hpp> has been deprecated. Please #include <boost/exception/all.hpp> instead.
#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>
#endif #endif

View File

@@ -8,6 +8,9 @@
// See http://www.boost.org/libs/utility/operators.htm for documentation. // See http://www.boost.org/libs/utility/operators.htm for documentation.
// Revision History // Revision History
// 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 // 24 May 07 Changed empty_base to depend on T, see
// http://svn.boost.org/trac/boost/ticket/979 // http://svn.boost.org/trac/boost/ticket/979
// 21 Oct 02 Modified implementation of operators to allow compilers with a // 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> > template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable2 : B 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 !static_cast<bool>(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 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 !(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 !(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> > template <class T, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable1 : B 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 !(y < x); } 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 !(x < y); } 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> > template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct equality_comparable2 : B 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 U& y, const T& x) { return !(x == y); } 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 !(y == x); } 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> > template <class T, class B = ::boost::detail::empty_base<T> >
struct equality_comparable1 : B 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". // A macro which produces "name_2left" from "name".
@@ -356,7 +359,7 @@ struct equivalent2 : B
{ {
friend bool operator==(const T& x, const U& 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);
} }
}; };
@@ -365,7 +368,7 @@ struct equivalent1 : B
{ {
friend bool operator==(const T&x, const T&y) 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 struct partially_ordered2 : B
{ {
friend bool operator<=(const T& x, const U& 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 T& x, const U& 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) friend bool operator>(const U& x, const T& y)
{ return y < x; } { return y < x; }
friend bool operator<(const U& x, const T& y) friend bool operator<(const U& x, const T& y)
{ return y > x; } { return y > x; }
friend bool operator<=(const U& x, const T& y) 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) 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> > 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) friend bool operator>(const T& x, const T& y)
{ return y < x; } { return y < x; }
friend bool operator<=(const T& x, const T& y) 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) 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) ----------------// // Combined operator classes (contributed by Daryle Walker) ----------------//
@@ -580,7 +583,35 @@ struct ordered_euclidian_ring_operators1
: totally_ordered1<T : totally_ordered1<T
, euclidian_ring_operators1<T, B , 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> > template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct input_iteratable struct input_iteratable
: equality_comparable1<T : equality_comparable1<T
@@ -837,6 +868,8 @@ BOOST_OPERATOR_TEMPLATE(field_operators)
BOOST_OPERATOR_TEMPLATE(ordered_field_operators) BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators) BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_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_TEMPLATE2(input_iteratable)
BOOST_OPERATOR_TEMPLATE1(output_iteratable) BOOST_OPERATOR_TEMPLATE1(output_iteratable)
BOOST_OPERATOR_TEMPLATE2(forward_iteratable) BOOST_OPERATOR_TEMPLATE2(forward_iteratable)

View File

@@ -173,6 +173,17 @@ class unwrap_reference
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # 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 } // namespace boost
#endif // #ifndef BOOST_REF_HPP_INCLUDED #endif // #ifndef BOOST_REF_HPP_INCLUDED

View File

@@ -7,6 +7,6 @@
#ifndef BOOST_SWAP_HPP #ifndef BOOST_SWAP_HPP
#define BOOST_SWAP_HPP #define BOOST_SWAP_HPP
#include "./utility/swap.hpp" #include "boost/utility/swap.hpp"
#endif #endif

View File

@@ -21,6 +21,17 @@ namespace boost
namespace detail 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 template<class T> struct addressof_impl
{ {
static inline T * f( T & v, long ) static inline T * f( T & v, long )
@@ -39,12 +50,40 @@ template<class T> struct addressof_impl
template<class T> T * addressof( T & v ) 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 ); 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 // Borland doesn't like casting an array reference to a char reference
// but these overloads work around the problem. // 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> template<typename T,std::size_t N>
T (*addressof(T (&t)[N]))[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); return reinterpret_cast<const T(*)[N]>(&t);
} }
# endif #endif
} // namespace boost } // namespace boost

View File

@@ -20,10 +20,69 @@
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)> struct tr1_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)> {}; : 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 #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 #undef BOOST_RESULT_OF_ARGS
#if BOOST_PP_ITERATION() >= 1 #if BOOST_PP_ITERATION() >= 1
@@ -32,14 +91,14 @@ namespace detail {
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_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; typedef R type;
}; };
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_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; 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)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (T0::*) struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
FArgs, false> FArgs, false>
{ {
@@ -56,7 +115,7 @@ struct result_of_impl<R (T0::*)
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (T0::*) struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const, const,
FArgs, false> FArgs, false>
@@ -66,7 +125,7 @@ struct result_of_impl<R (T0::*)
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (T0::*) struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
volatile, volatile,
FArgs, false> FArgs, false>
@@ -76,7 +135,7 @@ struct result_of_impl<R (T0::*)
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (T0::*) struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const volatile, const volatile,
FArgs, false> FArgs, false>

View File

@@ -10,13 +10,18 @@
#define BOOST_RESULT_OF_HPP #define BOOST_RESULT_OF_HPP
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/type_traits/ice.hpp> #include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/type.hpp> #include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor.hpp> #include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/bool.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 #ifndef BOOST_RESULT_OF_NUM_ARGS
# define BOOST_RESULT_OF_NUM_ARGS 10 # define BOOST_RESULT_OF_NUM_ARGS 10
@@ -25,13 +30,15 @@
namespace boost { namespace boost {
template<typename F> struct result_of; 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) #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail { namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) 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> template<typename F>
struct result_of_void_impl struct result_of_void_impl
@@ -51,8 +58,13 @@ struct result_of_void_impl<R (&)(void)>
typedef R type; typedef R type;
}; };
// Determine the return type of a function pointer or pointer to member.
template<typename F, typename FArgs> 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; typedef typename F::result_type type;
}; };
@@ -68,10 +80,10 @@ struct result_of_nested_result : F::template result<FArgs>
{}; {};
template<typename F, typename 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>, : mpl::if_<is_function_with_no_args<FArgs>,
result_of_void_impl<F>, result_of_void_impl<F>,
result_of_nested_result<F, FArgs> >::type result_of_nested_result<F, FArgs> >::type
{}; {};
} // end namespace detail } // end namespace detail

View File

@@ -7,6 +7,8 @@
// 21 Ago 2002 (Created) Fernando Cacciola // 21 Ago 2002 (Created) Fernando Cacciola
// 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker // 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 // 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
// //
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
@@ -22,6 +24,7 @@
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/cv_traits.hpp> #include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
#include <cstring> #include <cstring>
#include <new> #include <new>
@@ -88,12 +91,24 @@ class value_initialized
wrapper_address()->wrapper::~wrapper(); wrapper_address()->wrapper::~wrapper();
} }
T& data() const T const & data() const
{ {
return wrapper_address()->data; return wrapper_address()->data;
} }
operator T&() const { return this->data(); } T& data()
{
return wrapper_address()->data;
}
void swap(value_initialized & arg)
{
::boost::swap( this->data(), arg.data() );
}
operator T const &() const { return this->data(); }
operator T&() { return this->data(); }
} ; } ;
@@ -110,6 +125,12 @@ T& get ( value_initialized<T>& x )
return x.data() ; return x.data() ;
} }
template<class T>
void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
{
lhs.swap(rhs) ;
}
class initialized_value_t class initialized_value_t
{ {

View File

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

View File

@@ -132,18 +132,18 @@
class MyInt class MyInt
: boost::operators&lt;MyInt&gt; : 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; 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/=(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&amp;=(const MyInt&amp; x);
MyInt&amp; operator^=(const MyInt&amp; x); MyInt&amp; operator^=(const MyInt&amp; x);
MyInt&amp; operator++(); MyInt&amp; operator++();
MyInt&amp; operator--(); MyInt&amp; operator--();
}; };
</pre> </pre>
</blockquote> </blockquote>
@@ -345,7 +345,7 @@ class MyInt
</ul> </ul>
<p>As Daniel Kr&uuml;gler pointed out, this technique violates 14.6.5/2 <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. by the instantiation of e.g.
<code>less_than_comparable&lt;myclass&gt;</code> can not be found <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 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 optional template parameter <code>B</code>, which is not shown, for the
<a href="#chaining">base class chaining</a> technique.</p> <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"> <table cellpadding="5" border="1" align="center">
<caption> <caption>
Simple Arithmetic Operator Template Classes 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 created, <code>operator+=</code> is called on it and it is copied to the
function return value (which is another unnamed object of type function return value (which is another unnamed object of type
<code>T</code>). The standard doesn't generally allow the intermediate <code>T</code>). The standard doesn't generally allow the intermediate
object to be optimized away: object to be optimized away:
<blockquote> <blockquote>
3.7.2/2: Automatic storage duration<br> 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 unused, except that a class object or its copy may be eliminated as
specified in 12.8. specified in 12.8.
</blockquote> </blockquote>
The reference to 12.8 is important for us: The reference to 12.8 is important for us:
<blockquote> <blockquote>
12.8/15: Copying class objects<br> 12.8/15: Copying class objects<br>
@@ -942,7 +945,7 @@ T operator+( const T&amp; lhs, const T&amp; rhs )
</blockquote> </blockquote>
This optimization is known as the named return value optimization (NRVO), This optimization is known as the named return value optimization (NRVO),
which leads us to the following implementation for which leads us to the following implementation for
<code>operator+</code>: <code>operator+</code>:
<pre> <pre>
T operator+( const T&amp; lhs, const T&amp; rhs ) 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. 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 Without the NRVO, the NRVO-friendly code is no worse than the original
code showed above, but there is another possible implementation, which code showed above, but there is another possible implementation, which
has some very special properties: has some very special properties:
<pre> <pre>
T operator+( T lhs, const T&amp; rhs ) 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 will force the NRVO-friendly implementation to be used even for compilers
that don't implement the NRVO. <br> that don't implement the NRVO. <br>
<br> <br>
<h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3> <h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3>
<p>The following templates provide common groups of related operations. <p>The following templates provide common groups of related operations.
@@ -1420,9 +1423,9 @@ T operator+( T lhs, const T&amp; rhs )
<tr> <tr>
<td><code><a name= <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> <td>
<ul> <ul>
@@ -1439,9 +1442,9 @@ T operator+( T lhs, const T&amp; rhs )
<tr> <tr>
<td><code><a name= <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> 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> <td>
<ul> <ul>
@@ -1464,14 +1467,14 @@ T operator+( T lhs, const T&amp; rhs )
<tr> <tr>
<td><code><a name= <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> <td>
<ul> <ul>
<li><code><a href= <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= <li><code><a href=
"#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li> "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
@@ -1481,14 +1484,14 @@ T operator+( T lhs, const T&amp; rhs )
<tr> <tr>
<td><code><a name= <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> 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> <td>
<ul> <ul>
<li><code><a href= <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> U&gt;</a></code></li>
<li><code><a href="#totally_ordered2">totally_ordered&lt;T, <li><code><a href="#totally_ordered2">totally_ordered&lt;T,
@@ -1498,6 +1501,15 @@ T operator+( T lhs, const T&amp; rhs )
</tr> </tr>
</table> </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> <h3><a name="ex_oprs">Example</a> Templates</h3>
<p>The arithmetic operator class templates <code><a href= <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> <p>The <cite><a href="operators_test.cpp">operators_test.cpp</a></cite>
program demonstrates the use of the arithmetic operator templates, and program demonstrates the use of the arithmetic operator templates, and
can also be used to verify correct operation. Check the <a href= can also be used to verify correct operation. Check the compiler status
"../../status/compiler_status.html">compiler status report</a> for the report for the test results with selected platforms.</p>
test results with selected platforms.</p>
<h2><a name="deref">Dereference</a> Operators and Iterator Helpers</h2> <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> V, D, P, R&gt;</a></code></td>
<td> <td>
Supports the operations and has the requirements of Supports the operations and has the requirements of
<ul> <ul>
<li><code><a href="#input_iteratable">input_iteratable&lt;T, <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> "output_iterator_helper">output_iterator_helper&lt;T&gt;</a></code></td>
<td> <td>
Supports the operations and has the requirements of Supports the operations and has the requirements of
<ul> <ul>
<li><code><a href= <li><code><a href=
@@ -1886,7 +1897,7 @@ T operator+( T lhs, const T&amp; rhs )
R&gt;</a></code></td> R&gt;</a></code></td>
<td> <td>
Supports the operations and has the requirements of Supports the operations and has the requirements of
<ul> <ul>
<li><code><a href="#forward_iteratable">forward_iteratable&lt;T, <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> V, D, P, R&gt;</a></code></td>
<td> <td>
Supports the operations and has the requirements of Supports the operations and has the requirements of
<ul> <ul>
<li><code><a href= <li><code><a href=
@@ -1917,7 +1928,7 @@ T operator+( T lhs, const T&amp; rhs )
V, D, P, R&gt;</a></code></td> V, D, P, R&gt;</a></code></td>
<td> <td>
Supports the operations and has the requirements of Supports the operations and has the requirements of
<ul> <ul>
<li><code><a href= <li><code><a href=
@@ -1968,8 +1979,8 @@ struct function_output_iterator
template&lt;typename T&gt; template&lt;typename T&gt;
function_output_iterator&amp; operator=(T const&amp; value) function_output_iterator&amp; operator=(T const&amp; value)
{ {
this-&gt;func(value); this-&gt;func(value);
return *this; return *this;
} }
private: private:
@@ -2119,11 +2130,11 @@ public:
backward-compatible.</p> backward-compatible.</p>
<hr> <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; Beman Dawes, David Abrahams, 1999-2001.</p>
<p>Copyright &copy; Daniel Frey, 2002-2004.</p> <p>Copyright &copy; Daniel Frey, 2002-2009.</p>
<p>Use, modification, and distribution is subject to the Boost Software <p>Use, modification, and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file License, Version 1.0. (See accompanying file
<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt"> <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. // See http://www.boost.org/libs/utility for documentation.
// Revision History // Revision History
// 03 Apr 08 Added convertible_to_bool (Daniel Frey)
// 01 Oct 01 Added tests for "left" operators // 01 Oct 01 Added tests for "left" operators
// and new grouped operators. (Helmut Zeisel) // and new grouped operators. (Helmut Zeisel)
// 20 May 01 Output progress messages. Added tests for new operator // 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 char true_value(unsigned char x) { return x; }
unsigned short true_value(unsigned short 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 // The use of operators<> here tended to obscure
// interactions with certain compiler bugs // interactions with certain compiler bugs
template <class T> template <class T>
@@ -54,8 +72,10 @@ namespace
explicit Wrapped1( T v = T() ) : _value(v) {} explicit Wrapped1( T v = T() ) : _value(v) {}
T value() const { return _value; } T value() const { return _value; }
bool operator<(const Wrapped1& x) const { return _value < x._value; } convertible_to_bool operator<(const Wrapped1& x) const
bool operator==(const Wrapped1& x) const { return _value == x._value; } { return _value < x._value; }
convertible_to_bool operator==(const Wrapped1& x) const
{ return _value == x._value; }
Wrapped1& operator+=(const Wrapped1& x) Wrapped1& operator+=(const Wrapped1& x)
{ _value += x._value; return *this; } { _value += x._value; return *this; }
@@ -97,8 +117,10 @@ namespace
explicit Wrapped2( T v = T() ) : _value(v) {} explicit Wrapped2( T v = T() ) : _value(v) {}
T value() const { return _value; } T value() const { return _value; }
bool operator<(const Wrapped2& x) const { return _value < x._value; } convertible_to_bool operator<(const Wrapped2& x) const
bool operator==(const Wrapped2& x) const { return _value == x._value; } { return _value < x._value; }
convertible_to_bool operator==(const Wrapped2& x) const
{ return _value == x._value; }
Wrapped2& operator+=(const Wrapped2& x) Wrapped2& operator+=(const Wrapped2& x)
{ _value += x._value; return *this; } { _value += x._value; return *this; }
@@ -123,9 +145,13 @@ namespace
Wrapped2& operator++() { ++_value; return *this; } Wrapped2& operator++() { ++_value; return *this; }
Wrapped2& operator--() { --_value; return *this; } Wrapped2& operator--() { --_value; return *this; }
bool operator<(U u) const { return _value < u; } convertible_to_bool operator<(U u) const
bool operator>(U u) const { return _value > u; } { 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; }
Wrapped2& operator+=(U u) { _value += u; return *this; } Wrapped2& operator+=(U u) { _value += u; return *this; }
Wrapped2& operator-=(U u) { _value -= u; return *this; } 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) {} explicit Wrapped3( T v = T() ) : _value(v) {}
T value() const { return _value; } 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: private:
T _value; T _value;
@@ -174,10 +201,13 @@ namespace
explicit Wrapped4( T v = T() ) : _value(v) {} explicit Wrapped4( T v = T() ) : _value(v) {}
T value() const { return _value; } 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; } convertible_to_bool operator<(U u) const
bool operator>(U u) const { return _value > u; } { return _value < u; }
convertible_to_bool operator>(U u) const
{ return _value > u; }
private: private:
T _value; T _value;
@@ -198,11 +228,18 @@ namespace
Wrapped5(U u) : _value(u) {} Wrapped5(U u) : _value(u) {}
T value() const { return _value; } T value() const { return _value; }
bool operator<(const Wrapped5& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; } convertible_to_bool operator<(const Wrapped5& x) const
bool operator>(U u) const { return _value > u; } { return _value < x._value; }
bool operator==(const Wrapped5& u) const { return _value == u._value; } convertible_to_bool operator<(U u) const
bool operator==(U u) const { return _value == u; } { 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/=(const Wrapped5& u) { _value /= u._value; return *this;}
Wrapped5& operator/=(U u) { _value /= u; return *this;} Wrapped5& operator/=(U u) { _value /= u; return *this;}
Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;} Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
@@ -221,8 +258,8 @@ namespace
// U must be convertible to T // U must be convertible to T
template <class T, class U> template <class T, class U>
class Wrapped6 class Wrapped6
: boost::ordered_euclidian_ring_operators2<Wrapped6<T, U>, U> : boost::ordered_euclidean_ring_operators2<Wrapped6<T, U>, U>
, boost::ordered_euclidian_ring_operators1<Wrapped6<T, U> > , boost::ordered_euclidean_ring_operators1<Wrapped6<T, U> >
{ {
public: public:
explicit Wrapped6( T v = T() ) : _value(v) {} explicit Wrapped6( T v = T() ) : _value(v) {}
@@ -231,11 +268,18 @@ namespace
Wrapped6(U u) : _value(u) {} Wrapped6(U u) : _value(u) {}
T value() const { return _value; } T value() const { return _value; }
bool operator<(const Wrapped6& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; } convertible_to_bool operator<(const Wrapped6& x) const
bool operator>(U u) const { return _value > u; } { return _value < x._value; }
bool operator==(const Wrapped6& u) const { return _value == u._value; } convertible_to_bool operator<(U u) const
bool operator==(U u) const { return _value == u; } { 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%=(const Wrapped6& u) { _value %= u._value; return *this;}
Wrapped6& operator%=(U u) { _value %= u; return *this;} Wrapped6& operator%=(U u) { _value %= u; return *this;}
Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; 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> template <class X1, class Y1, class X2, class Y2>
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{ {
BOOST_CHECK( (x1 < y1) == (x2 < y2) ); BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
BOOST_CHECK( (x1 <= y1) == (x2 <= y2) ); BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
BOOST_CHECK( (x1 >= y1) == (x2 >= y2) ); BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
BOOST_CHECK( (x1 > y1) == (x2 > y2) ); BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
} }
template <class X1, class Y1, class X2, class Y2> template <class X1, class Y1, class X2, class Y2>
@@ -293,8 +337,8 @@ namespace
template <class X1, class Y1, class X2, class Y2> template <class X1, class Y1, class X2, class Y2>
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{ {
BOOST_CHECK( (x1 == y1) == (x2 == y2) ); BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
BOOST_CHECK( (x1 != y1) == (x2 != y2) ); BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
} }
template <class X1, class Y1, class X2, class 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) ); PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
BOOST_CHECK( i2 == i ); BOOST_CHECK( static_cast<bool>(i2 == i) );
BOOST_CHECK( i1 != i2 ); BOOST_CHECK( static_cast<bool>(i1 != i2) );
BOOST_CHECK( i1 < i2 ); BOOST_CHECK( static_cast<bool>(i1 < i2) );
BOOST_CHECK( i1 <= i2 ); BOOST_CHECK( static_cast<bool>(i1 <= i2) );
BOOST_CHECK( i <= i2 ); BOOST_CHECK( static_cast<bool>(i <= i2) );
BOOST_CHECK( i2 > i1 ); BOOST_CHECK( static_cast<bool>(i2 > i1) );
BOOST_CHECK( i2 >= i1 ); BOOST_CHECK( static_cast<bool>(i2 >= i1) );
BOOST_CHECK( i2 >= i ); BOOST_CHECK( static_cast<bool>(i2 >= i) );
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) ); PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) ); 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) ); PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
BOOST_CHECK( j2 == j ); BOOST_CHECK( static_cast<bool>(j2 == j) );
BOOST_CHECK( 2 == j ); BOOST_CHECK( static_cast<bool>(2 == j) );
BOOST_CHECK( j2 == 2 ); BOOST_CHECK( static_cast<bool>(j2 == 2) );
BOOST_CHECK( j == j2 ); BOOST_CHECK( static_cast<bool>(j == j2) );
BOOST_CHECK( j1 != j2 ); BOOST_CHECK( static_cast<bool>(j1 != j2) );
BOOST_CHECK( j1 != 2 ); BOOST_CHECK( static_cast<bool>(j1 != 2) );
BOOST_CHECK( 1 != j2 ); BOOST_CHECK( static_cast<bool>(1 != j2) );
BOOST_CHECK( j1 < j2 ); BOOST_CHECK( static_cast<bool>(j1 < j2) );
BOOST_CHECK( 1 < j2 ); BOOST_CHECK( static_cast<bool>(1 < j2) );
BOOST_CHECK( j1 < 2 ); BOOST_CHECK( static_cast<bool>(j1 < 2) );
BOOST_CHECK( j1 <= j2 ); BOOST_CHECK( static_cast<bool>(j1 <= j2) );
BOOST_CHECK( 1 <= j2 ); BOOST_CHECK( static_cast<bool>(1 <= j2) );
BOOST_CHECK( j1 <= j ); BOOST_CHECK( static_cast<bool>(j1 <= j) );
BOOST_CHECK( j <= j2 ); BOOST_CHECK( static_cast<bool>(j <= j2) );
BOOST_CHECK( 2 <= j2 ); BOOST_CHECK( static_cast<bool>(2 <= j2) );
BOOST_CHECK( j <= 2 ); BOOST_CHECK( static_cast<bool>(j <= 2) );
BOOST_CHECK( j2 > j1 ); BOOST_CHECK( static_cast<bool>(j2 > j1) );
BOOST_CHECK( 2 > j1 ); BOOST_CHECK( static_cast<bool>(2 > j1) );
BOOST_CHECK( j2 > 1 ); BOOST_CHECK( static_cast<bool>(j2 > 1) );
BOOST_CHECK( j2 >= j1 ); BOOST_CHECK( static_cast<bool>(j2 >= j1) );
BOOST_CHECK( 2 >= j1 ); BOOST_CHECK( static_cast<bool>(2 >= j1) );
BOOST_CHECK( j2 >= 1 ); BOOST_CHECK( static_cast<bool>(j2 >= 1) );
BOOST_CHECK( j2 >= j ); BOOST_CHECK( static_cast<bool>(j2 >= j) );
BOOST_CHECK( 2 >= j ); BOOST_CHECK( static_cast<bool>(2 >= j) );
BOOST_CHECK( j2 >= 2 ); BOOST_CHECK( static_cast<bool>(j2 >= 2) );
BOOST_CHECK( (j1 + 2) == 3 ); BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
BOOST_CHECK( (1 + j2) == 3 ); BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) ); PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
BOOST_CHECK( (j + 2) == 5 ); BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
BOOST_CHECK( (3 + j2) == 5 ); BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 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) ); PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
BOOST_CHECK( (j * 2) == 8 ); BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
BOOST_CHECK( (4 * j2) == 8 ); BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 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) ); 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 = j % ( j - j1 )), (j.value() == 1) );
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) ); PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
BOOST_CHECK( (1 | j2 | j) == 7 ); BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
BOOST_CHECK( (j1 | 2 | j) == 7 ); BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
BOOST_CHECK( (j1 | j2 | 4) == 7 ); BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) ); PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
BOOST_CHECK( (7 & j2) == 2 ); BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
BOOST_CHECK( (j & 2) == 2 ); BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) ); PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) ); PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
BOOST_CHECK( (3 ^ j1) == 2 ); BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
BOOST_CHECK( (j ^ 1) == 2 ); BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) ); PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) ); PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
BOOST_CHECK( (j1 << 2) == 4 ); BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
BOOST_CHECK( (j2 << 1) == 4 ); BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) ); PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
BOOST_CHECK( (j >> 2) == 1 ); BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
BOOST_CHECK( (j2 >> 1) == 1 ); BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) ); PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
cout << "Performed tests on MyLong objects.\n"; cout << "Performed tests on MyLong objects.\n";
@@ -741,14 +785,14 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) ); PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
BOOST_CHECK( k2 == k ); BOOST_CHECK( static_cast<bool>(k2 == k) );
BOOST_CHECK( k1 != k2 ); BOOST_CHECK( static_cast<bool>(k1 != k2) );
BOOST_CHECK( k1 < k2 ); BOOST_CHECK( static_cast<bool>(k1 < k2) );
BOOST_CHECK( k1 <= k2 ); BOOST_CHECK( static_cast<bool>(k1 <= k2) );
BOOST_CHECK( k <= k2 ); BOOST_CHECK( static_cast<bool>(k <= k2) );
BOOST_CHECK( k2 > k1 ); BOOST_CHECK( static_cast<bool>(k2 > k1) );
BOOST_CHECK( k2 >= k1 ); BOOST_CHECK( static_cast<bool>(k2 >= k1) );
BOOST_CHECK( k2 >= k ); BOOST_CHECK( static_cast<bool>(k2 >= k) );
cout << "Performed tests on MyChar objects.\n"; cout << "Performed tests on MyChar objects.\n";
@@ -764,31 +808,31 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) ); PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
BOOST_CHECK( l2 == l ); BOOST_CHECK( static_cast<bool>(l2 == l) );
BOOST_CHECK( 2 == l ); BOOST_CHECK( static_cast<bool>(2 == l) );
BOOST_CHECK( l2 == 2 ); BOOST_CHECK( static_cast<bool>(l2 == 2) );
BOOST_CHECK( l == l2 ); BOOST_CHECK( static_cast<bool>(l == l2) );
BOOST_CHECK( l1 != l2 ); BOOST_CHECK( static_cast<bool>(l1 != l2) );
BOOST_CHECK( l1 != 2 ); BOOST_CHECK( static_cast<bool>(l1 != 2) );
BOOST_CHECK( 1 != l2 ); BOOST_CHECK( static_cast<bool>(1 != l2) );
BOOST_CHECK( l1 < l2 ); BOOST_CHECK( static_cast<bool>(l1 < l2) );
BOOST_CHECK( 1 < l2 ); BOOST_CHECK( static_cast<bool>(1 < l2) );
BOOST_CHECK( l1 < 2 ); BOOST_CHECK( static_cast<bool>(l1 < 2) );
BOOST_CHECK( l1 <= l2 ); BOOST_CHECK( static_cast<bool>(l1 <= l2) );
BOOST_CHECK( 1 <= l2 ); BOOST_CHECK( static_cast<bool>(1 <= l2) );
BOOST_CHECK( l1 <= l ); BOOST_CHECK( static_cast<bool>(l1 <= l) );
BOOST_CHECK( l <= l2 ); BOOST_CHECK( static_cast<bool>(l <= l2) );
BOOST_CHECK( 2 <= l2 ); BOOST_CHECK( static_cast<bool>(2 <= l2) );
BOOST_CHECK( l <= 2 ); BOOST_CHECK( static_cast<bool>(l <= 2) );
BOOST_CHECK( l2 > l1 ); BOOST_CHECK( static_cast<bool>(l2 > l1) );
BOOST_CHECK( 2 > l1 ); BOOST_CHECK( static_cast<bool>(2 > l1) );
BOOST_CHECK( l2 > 1 ); BOOST_CHECK( static_cast<bool>(l2 > 1) );
BOOST_CHECK( l2 >= l1 ); BOOST_CHECK( static_cast<bool>(l2 >= l1) );
BOOST_CHECK( 2 >= l1 ); BOOST_CHECK( static_cast<bool>(2 >= l1) );
BOOST_CHECK( l2 >= 1 ); BOOST_CHECK( static_cast<bool>(l2 >= 1) );
BOOST_CHECK( l2 >= l ); BOOST_CHECK( static_cast<bool>(l2 >= l) );
BOOST_CHECK( 2 >= l ); BOOST_CHECK( static_cast<bool>(2 >= l) );
BOOST_CHECK( l2 >= 2 ); BOOST_CHECK( static_cast<bool>(l2 >= 2) );
cout << "Performed tests on MyShort objects.\n"; cout << "Performed tests on MyShort objects.\n";
@@ -807,37 +851,37 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) ); PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
BOOST_CHECK( di2 == di ); BOOST_CHECK( static_cast<bool>(di2 == di) );
BOOST_CHECK( 2 == di ); BOOST_CHECK( static_cast<bool>(2 == di) );
BOOST_CHECK( di == 2 ); BOOST_CHECK( static_cast<bool>(di == 2) );
BOOST_CHECK( di1 < di2 ); BOOST_CHECK( static_cast<bool>(di1 < di2) );
BOOST_CHECK( 1 < di2 ); BOOST_CHECK( static_cast<bool>(1 < di2) );
BOOST_CHECK( di1 <= di2 ); BOOST_CHECK( static_cast<bool>(di1 <= di2) );
BOOST_CHECK( 1 <= di2 ); BOOST_CHECK( static_cast<bool>(1 <= di2) );
BOOST_CHECK( di2 > di1 ); BOOST_CHECK( static_cast<bool>(di2 > di1) );
BOOST_CHECK( di2 > 1 ); BOOST_CHECK( static_cast<bool>(di2 > 1) );
BOOST_CHECK( di2 >= di1 ); BOOST_CHECK( static_cast<bool>(di2 >= di1) );
BOOST_CHECK( di2 >= 1 ); BOOST_CHECK( static_cast<bool>(di2 >= 1) );
BOOST_CHECK( di1 / di2 == half ); BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
BOOST_CHECK( di1 / 2 == half ); BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
BOOST_CHECK( 1 / di2 == half ); BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=2) == half) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=di2) == half) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
BOOST_CHECK( di1 * di2 == di2 ); BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
BOOST_CHECK( di1 * 2 == di2 ); BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
BOOST_CHECK( 1 * di2 == di2 ); BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=2) == di2) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=di2) == di2) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
BOOST_CHECK( di2 - di1 == di1 ); BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
BOOST_CHECK( di2 - 1 == di1 ); BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
BOOST_CHECK( 2 - di1 == di1 ); BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=1) == di1) ); PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=di1) == di1) ); PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
BOOST_CHECK( di1 + di1 == di2 ); BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
BOOST_CHECK( di1 + 1 == di2 ); BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
BOOST_CHECK( 1 + di1 == di2 ); BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=di1) == di2) ); PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
cout << "Performed tests on MyDoubleInt objects.\n"; cout << "Performed tests on MyDoubleInt objects.\n";
@@ -854,42 +898,42 @@ test_main( int , char * [] )
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) ); PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
BOOST_CHECK( li2 == li ); BOOST_CHECK( static_cast<bool>(li2 == li) );
BOOST_CHECK( 2 == li ); BOOST_CHECK( static_cast<bool>(2 == li) );
BOOST_CHECK( li == 2 ); BOOST_CHECK( static_cast<bool>(li == 2) );
BOOST_CHECK( li1 < li2 ); BOOST_CHECK( static_cast<bool>(li1 < li2) );
BOOST_CHECK( 1 < li2 ); BOOST_CHECK( static_cast<bool>(1 < li2) );
BOOST_CHECK( li1 <= li2 ); BOOST_CHECK( static_cast<bool>(li1 <= li2) );
BOOST_CHECK( 1 <= li2 ); BOOST_CHECK( static_cast<bool>(1 <= li2) );
BOOST_CHECK( li2 > li1 ); BOOST_CHECK( static_cast<bool>(li2 > li1) );
BOOST_CHECK( li2 > 1 ); BOOST_CHECK( static_cast<bool>(li2 > 1) );
BOOST_CHECK( li2 >= li1 ); BOOST_CHECK( static_cast<bool>(li2 >= li1) );
BOOST_CHECK( li2 >= 1 ); BOOST_CHECK( static_cast<bool>(li2 >= 1) );
BOOST_CHECK( li1 % li2 == li1 ); BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
BOOST_CHECK( li1 % 2 == li1 ); BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
BOOST_CHECK( 1 % li2 == li1 ); BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=2) == li1) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=li2) == li1) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
BOOST_CHECK( li1 / li2 == 0 ); BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
BOOST_CHECK( li1 / 2 == 0 ); BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
BOOST_CHECK( 1 / li2 == 0 ); BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=2) == 0) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=li2) == 0) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
BOOST_CHECK( li1 * li2 == li2 ); BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
BOOST_CHECK( li1 * 2 == li2 ); BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
BOOST_CHECK( 1 * li2 == li2 ); BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=2) == li2) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=li2) == li2) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
BOOST_CHECK( li2 - li1 == li1 ); BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
BOOST_CHECK( li2 - 1 == li1 ); BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
BOOST_CHECK( 2 - li1 == li1 ); BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=1) == li1) ); PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=li1) == li1) ); PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
BOOST_CHECK( li1 + li1 == li2 ); BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
BOOST_CHECK( li1 + 1 == li2 ); BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
BOOST_CHECK( 1 + li1 == li2 ); BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) ); PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
cout << "Performed tests on MyLongInt objects.\n"; 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 } // 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 * []) int test_main(int, char * [])
{ {
ref_wrapper<int>::test(1); ref_wrapper<int>::test(1);
ref_wrapper<int const>::test(1); ref_wrapper<int const>::test(1);
unwrap_test();
return 0; return 0;
} }

View File

@@ -7,14 +7,18 @@
</head> </head>
<body> <body>
<!-- Page header --> <!-- Page header -->
<h2>
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/> <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> <h1>Swap</h1>
<p> <p>
<tt>template&lt;class T&gt; void swap(T&amp; <em>left</em>, T&amp; <em>right</em>);</tt> <tt>template&lt;class T&gt; void swap(T&amp; <em>left</em>, T&amp; <em>right</em>);</tt>
</p> </p>
<!-- Intoduction --> <!-- Introduction -->
<p> <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. 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> </p>
@@ -24,10 +28,10 @@
<p> <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> 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> <p>
The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces. The alternative to using argument dependent lookup in this situation is to provide a template specialization of <tt>std::swap</tt> for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces.
</p> </p>
<p> <p>
<tt>boost::swap</tt> also supports swapping built-in arrays. Note that <tt>std::swap</tt> doesn't yet do so, but a request to add an overload of <tt>std::swap</tt> for built-in arrays has been well-received by the Library Working Group of the C++ Standards Committee<sup><a href="#ref2">2</a></sup>. <tt>boost::swap</tt> also supports swapping built-in arrays. Note that <tt>std::swap</tt> originally did not do so, but a request to add an overload of <tt>std::swap</tt> for built-in arrays has been accepted by the C++ Standards Committee<sup><a href="#ref2">2</a></sup>.
</p> </p>
<!-- Exception Safety --> <!-- Exception Safety -->
@@ -45,11 +49,11 @@
</ul> </ul>
<p>Or:</p> <p>Or:</p>
<ul> <ul>
<li>A function with the signature <tt>swap(T&,T&)</tt> is available via argument dependent lookup</li> <li>A function with the signature <tt>swap(T&amp;,T&amp;)</tt> is available via argument dependent lookup</li>
</ul> </ul>
<p>Or:</p> <p>Or:</p>
<ul> <ul>
<li>A template specialization of std::swap exists for T</li> <li>A template specialization of <tt>std::swap</tt> exists for T</li>
</ul> </ul>
<p>Or:</p> <p>Or:</p>
<ul> <ul>
@@ -73,20 +77,20 @@
<em><a href="mailto:Joseph.Gauterin@googlemail.com">Joseph Gauterin</a></em> - for the initial idea, implementation, tests, and documentation <em><a href="mailto:Joseph.Gauterin@googlemail.com">Joseph Gauterin</a></em> - for the initial idea, implementation, tests, and documentation
</li> </li>
<li> <li>
<em>Steven Wanatabe</em> - for the idea to make boost::swap less specialized than std::swap, thereby allowing the function to have the name 'swap' without introducing ambiguity <em>Steven Watanabe</em> - for the idea to make <tt>boost::swap</tt> less specialized than <tt>std::swap</tt>, thereby allowing the function to have the name 'swap' without introducing ambiguity
</li> </li>
</ul> </ul>
<!-- References --> <!-- References -->
<hr/> <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="ref1"/>[1]</sup>Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"</p>
<p><sup><a id="ref2"/>[2]</sup><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#809">LWG issue 809 (std::swap should be overloaded for array types)</a></p> <p><sup><a id="ref2"/>[2]</sup><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809">LWG Defect Report 809 (std::swap should be overloaded for array types)</a></p>
<!-- Copyright info --> <!-- Copyright info -->
<hr/> <hr/>
<p>Revised: 4 August 2008</p> <p>Revised: 08 September 2009</p>
<p> <p>
Copyright 2007, 2008 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. Copyright 2007 - 2009 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0.
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.) (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> </p>

View File

@@ -29,5 +29,9 @@ test-suite utility/swap
[ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] [ run std_vector_of_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 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 no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run swap_arrays.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] [ run array_of_array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_template.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
; ;

View File

@@ -4,6 +4,8 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
#include <boost/utility/swap.hpp> #include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN #define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
@@ -33,32 +35,8 @@ namespace std
} }
} }
// Tests swapping 1-dimensional arrays.
void test_swapping_1D_arrays()
{
const std::size_t dimension = 2;
const swap_test_class initial_array1[dimension] = { swap_test_class(1), swap_test_class(2) };
const swap_test_class initial_array2[dimension] = { swap_test_class(3), swap_test_class(4) };
swap_test_class array1[dimension];
swap_test_class array2[dimension];
std::copy(initial_array1, initial_array1 + dimension, array1); int test_main(int, char*[])
std::copy(initial_array2, initial_array2 + dimension, array2);
swap_test_class::reset();
boost::swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + dimension, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + dimension, initial_array1));
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), dimension);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
}
// Tests swapping 2-dimensional arrays.
void test_swapping_2D_arrays()
{ {
const std::size_t first_dimension = 3; const std::size_t first_dimension = 3;
const std::size_t second_dimension = 4; const std::size_t second_dimension = 4;
@@ -76,7 +54,6 @@ void test_swapping_2D_arrays()
ptr2[i].set_data( static_cast<int>(i + number_of_elements) ); ptr2[i].set_data( static_cast<int>(i + number_of_elements) );
} }
swap_test_class::reset();
boost::swap(array1, array2); boost::swap(array1, array2);
for (std::size_t i = 0; i < number_of_elements; ++i) for (std::size_t i = 0; i < number_of_elements; ++i)
@@ -87,14 +64,6 @@ void test_swapping_2D_arrays()
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements); BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
}
int test_main(int, char*[])
{
test_swapping_1D_arrays();
test_swapping_2D_arrays();
return 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

@@ -1,4 +1,4 @@
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker // Copyright (c) 2008 - 2010 Joseph Gauterin, Niels Dekker
// //
// Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,9 +17,9 @@
int test_main(int, char*[]) int test_main(int, char*[])
{ {
typedef std::bitset<8> bitset_type; typedef std::bitset<8> bitset_type;
const bitset_type initial_value1 = 1ul; const bitset_type initial_value1 = 1;
const bitset_type initial_value2 = 2ul; const bitset_type initial_value2 = 2;
bitset_type object1 = initial_value1; bitset_type object1 = initial_value1;
bitset_type object2 = initial_value2; bitset_type object2 = initial_value2;

View File

@@ -12,7 +12,7 @@
class swap_test_class class swap_test_class
{ {
int m_data; int m_data;
public: public:
explicit swap_test_class(int arg = 0) explicit swap_test_class(int arg = 0)
: :

View File

@@ -11,7 +11,9 @@ import testing ;
# Please keep the tests ordered by filename # Please keep the tests ordered by filename
test-suite utility test-suite utility
: :
[ run ../addressof_fn_test.cpp ]
[ run ../addressof_test.cpp ] [ run ../addressof_test.cpp ]
[ run ../addressof_test2.cpp ]
[ run ../assert_test.cpp ] [ run ../assert_test.cpp ]
[ run ../base_from_member_test.cpp ] [ run ../base_from_member_test.cpp ]
[ run ../binary_search_test.cpp ] [ run ../binary_search_test.cpp ]

View File

@@ -5,41 +5,109 @@
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_RESULT_OF_USE_DECLTYPE
// For more information, see http://www.boost.org/libs/utility // For more information, see http://www.boost.org/libs/utility
#include <boost/utility/result_of.hpp> #include <boost/utility/result_of.hpp>
#include <utility> #include <utility>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.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 struct int_result_of
{ {
template<typename F> struct result { typedef int type; }; 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; typedef int result_type;
template<typename F> struct result { typedef float type; }; template<typename F> struct result { typedef float type; };
char operator()(char);
}; };
template<typename T> 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> template<typename T>
struct int_result_of_template struct int_result_of_template
{ {
template<typename F> struct result; template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef int type; }; 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> 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; typedef int result_type;
template<typename F> struct result; template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef float type; }; 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 {}; 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_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(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<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_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>(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<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<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_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_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::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<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<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; 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> <html>
<head> <head>
<title>Boost: throw_exception.hpp documentation</title> <meta http-equiv=refresh content="0; URL=../exception/doc/throw_exception.html">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Automatic redirection</title>
</head> </head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> <body>
<table border="0" width="100%"> Automatic redirection failed, please go to
<tr> <a href="../exception/doc/throw_exception.html">throw_exception.html</a>.&nbsp;<hr>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> <p><EFBFBD> Copyright Beman Dawes, 2001</p>
</td> <p>Distributed under the Boost Software License, Version 1.0. (See accompanying
<td align="center"> file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
<h1>throw_exception.hpp</h1> at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</td> </body>
</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>
</html> </html>

View File

@@ -154,11 +154,13 @@ void f() {
...,t<em>N</em>)</code>. The implementation permits ...,t<em>N</em>)</code>. The implementation permits
the type <code>F</code> to be a function pointer, the type <code>F</code> to be a function pointer,
function reference, member function pointer, or class function reference, member function pointer, or class
type. When <code>F</code> is a class type with a type.</p> <p>If your compiler does not support
member type <code>result_type</code>, <code>decltype</code>, then when <code>F</code> is a
class type with a member type <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ..., <code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;</code> is T<em>N</em>)&gt;</code> is
<code>F::result_type</code>. Otherwise, <code>F::result_type</code>. When <code>F</code>
does not contain <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ..., <code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;</code> is <code>F::result&lt;F(T1, T<em>N</em>)&gt;</code> is <code>F::result&lt;F(T1,
T2, ..., T<em>N</em>)&gt;::type</code> when T2, ..., T<em>N</em>)&gt;::type</code> when

View File

@@ -253,7 +253,33 @@ its internal data, prior to constructing the object that it contains.
<h2><a name="val_init"><code>template class value_initialized&lt;T&gt;</code></a></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 <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>) to <code>'T&amp;'</code> whose wrapped object (data member of type <code>T</code>)
@@ -271,47 +297,49 @@ its internal data, prior to constructing the object that it contains.
<code>T&amp;</code>, the member function <code>data()</code>, or the <code>T&amp;</code>, the member function <code>data()</code>, or the
non-member function <code>get()</code>: </p> 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. <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 Mutable objects can be modified directly from within the wrapper but constant
objects cannot:</p> 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> <h3>Warning:</h3>
<p>Both the conversion operator and the <code>data()</code> member function <p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
are <code>const</code> in order to allow access to the wrapped object allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
from a constant wrapper:</p> 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 <p>The reason for this obscure behavior was that some compilers
it is itself <code>const</code>. As a consequence, if <code>T</code> is didn't accept the following valid code:</p>
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>
<pre>struct X<br>{<br> operator int&amp;() ;<br> operator int const&amp;() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre> <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. <p>The current version of <code>value_initialized</code> no longer has this obscure behavior.
This complaint is incorrect, but the only workaround that I know of is 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.
to provide only one of them, which leads to the obscure behavior just explained.<br> <br>
</p> </p>
<h3>Recommended practice: The non-member get() idiom</h3> <h3>Recommended practice: The non-member get() idiom</h3>
<p>The obscure behavior of being able to modify a non-<code>const</code> <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> 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> <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_value"><code>initialized_value</code></a></h2> <h2><a name="initialized_value"><code>initialized_value</code></a></h2>
<pre> <pre>
@@ -379,9 +407,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
</p> </p>
<hr> <hr>
<p>Revised 23 May 2008</p> <p>Revised 03 October 2009</p>
<p>&copy; Copyright Fernando Cacciola, 2002, 2008.</p> <p>&copy; Copyright Fernando Cacciola, 2002, 2009.</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>

View File

@@ -9,6 +9,7 @@
// 21 Ago 2002 (Created) Fernando Cacciola // 21 Ago 2002 (Created) Fernando Cacciola
// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker // 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
// 23 May 2008 (Added tests regarding initialized_value) 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 <cstring> // For memcmp.
#include <iostream> #include <iostream>
@@ -28,9 +29,9 @@
// //
struct POD 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 ) friend std::ostream& operator << ( std::ostream& os, POD const& pod )
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; } { 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> template<class T>
void check_initialized_value ( T const& y ) 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 // and this type (NonPOD), because the following statement
// won't compile on this particular compiler version: // won't compile on this particular compiler version:
// NonPOD initializedValue = boost::initialized_value() ; // NonPOD initializedValue = boost::initialized_value() ;
// //
// This is caused by a compiler bug, that is fixed with a newer version // 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 // 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) // 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::value_initialized<T> const x_c ;
BOOST_CHECK ( y == x_c ) ; BOOST_CHECK ( y == x_c ) ;
BOOST_CHECK ( y == boost::get(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 ; x_c_ref = z ;
BOOST_CHECK ( x_c == z ) ; BOOST_CHECK ( x_c == z ) ;
@@ -261,7 +291,7 @@ int test_main(int, char **)
{ {
BOOST_CHECK ( test( 0,1234 ) ) ; BOOST_CHECK ( test( 0,1234 ) ) ;
BOOST_CHECK ( test( 0.0,12.34 ) ) ; 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") ) ) ) ; BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
NonPOD NonPOD_object( std::string("NonPOD_object") ); 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_copy_constructed);
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called); 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; return 0;
} }
unsigned int expected_failures = 0; unsigned int expected_failures = 0;