Compare commits

..

1 Commits

Author SHA1 Message Date
922ce7b8ae Branch at revision 46530
[SVN r46531]
2008-06-19 18:57:10 +00:00
10 changed files with 72 additions and 409 deletions

View File

@ -13,26 +13,6 @@
<itemizedlist spacing="compact">
<listitem><para><bold>Version 1.37.0</bold>: </para>
<itemizedlist spacing="compact">
<listitem><para>Improved the performance of Boost.Function's
swap() operation for large function objects. Original patch
contributed by Niels Dekker.</para></listitem>
<listitem><para>Added a new header &lt;boost/function/function_typeof.hpp&gt; that provides support for using the Boost.Typeof library on Boost.Function objects.</para></listitem>
<listitem><para>Added a new header &lt;boost/function/function_fwd.hpp&gt; that provides support for using the Boost.Typeof library on Boost.Function objects.</para></listitem>
<listitem><para>The <methodname alt="boost::function::target">target</methodname>()
function now respects the cv-qualifiers of function objects
stored by reference
(using <classname>boost::reference_wrapper</classname>), such
that a reference to a <code>const</code> function object cannot
be accessed as a reference to a non-<code>const</code> function
object.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para><bold>Version 1.36.0</bold>: </para>
<itemizedlist spacing="compact">
<listitem><para>Boost.Function now implements allocator support

View File

@ -18,11 +18,8 @@
#include <typeinfo>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/composite_traits.hpp>
#include <boost/type_traits/ice.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/workaround.hpp>
@ -33,7 +30,6 @@
# include "boost/mpl/bool.hpp"
#endif
#include <boost/function_equal.hpp>
#include <boost/function/function_fwd.hpp>
#if defined(BOOST_MSVC)
# pragma warning( push )
@ -67,7 +63,22 @@
# define BOOST_FUNCTION_TARGET_FIX(x)
#endif // not MSVC
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
// Work around a compiler bug.
// boost::python::objects::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace objects {
class function;
}}}
#endif
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \
typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \
(::boost::is_integral<Functor>::value)>::value), \
@ -81,6 +92,22 @@
Type>::type
#endif
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
namespace boost {
template<typename Signature>
class function;
template<typename Signature>
inline void swap(function<Signature>& f1,
function<Signature>& f2)
{
f1.swap(f2);
}
} // end namespace boost
#endif // have partial specialization
namespace boost {
namespace detail {
namespace function {
@ -95,18 +122,11 @@ namespace boost {
union function_buffer
{
// For pointers to function objects
mutable void* obj_ptr;
void* obj_ptr;
// For pointers to std::type_info objects
struct type_t {
// (get_functor_type_tag, check_functor_type_tag).
const BOOST_FUNCTION_STD_NS::type_info* type;
// Whether the type is const-qualified.
bool const_qualified;
// Whether the type is volatile-qualified.
bool volatile_qualified;
} type;
// (get_functor_type_tag, check_functor_type_tag).
const void* const_obj_ptr;
// For function pointers of all kinds
mutable void (*func_ptr)();
@ -117,14 +137,6 @@ namespace boost {
void* obj_ptr;
} bound_memfunc_ptr;
// For references to function objects. We explicitly keep
// track of the cv-qualifiers on the object referenced.
struct obj_ref_t {
mutable void* obj_ptr;
bool is_const_qualified;
bool is_volatile_qualified;
} obj_ref;
// To relax aliasing constraints
mutable char data;
};
@ -156,7 +168,6 @@ namespace boost {
// The operation type to perform on the given functor/function pointer
enum functor_manager_operation_type {
clone_functor_tag,
move_functor_tag,
destroy_functor_tag,
check_functor_type_tag,
get_functor_type_tag
@ -198,40 +209,29 @@ namespace boost {
{
switch (op) {
case clone_functor_tag:
out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
return;
case move_functor_tag:
out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
in_buffer.obj_ref.obj_ptr = 0;
out_buffer.obj_ptr = in_buffer.obj_ptr;
return;
case destroy_functor_tag:
out_buffer.obj_ref.obj_ptr = 0;
out_buffer.obj_ptr = 0;
return;
case check_functor_type_tag:
{
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
// Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away.
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
&& (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified
|| out_buffer.type.volatile_qualified))
out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr;
// DPG TBD: Since we're only storing a pointer, it's
// possible that the user could ask for a base class or
// derived class. Is that okay?
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
}
return;
case get_functor_type_tag:
out_buffer.type.type = &typeid(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
out_buffer.const_obj_ptr = &typeid(F);
return;
}
}
@ -277,22 +277,15 @@ namespace boost {
{
if (op == clone_functor_tag)
out_buffer.func_ptr = in_buffer.func_ptr;
else if (op == move_functor_tag) {
out_buffer.func_ptr = in_buffer.func_ptr;
in_buffer.func_ptr = 0;
} else if (op == destroy_functor_tag)
else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
@ -301,28 +294,20 @@ namespace boost {
manage_small(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op)
{
if (op == clone_functor_tag || op == move_functor_tag) {
if (op == clone_functor_tag) {
const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data);
new ((void*)&out_buffer.data) functor_type(*in_functor);
if (op == move_functor_tag) {
reinterpret_cast<functor_type*>(&in_buffer.data)->~Functor();
}
} else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
} else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.data;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
};
@ -362,26 +347,19 @@ namespace boost {
(const functor_type*)(in_buffer.obj_ptr);
functor_type* new_f = new functor_type(*f);
out_buffer.obj_ptr = new_f;
} else if (op == move_functor_tag) {
out_buffer.obj_ptr = in_buffer.obj_ptr;
in_buffer.obj_ptr = 0;
} else if (op == destroy_functor_tag) {
/* Cast from the void pointer to the functor pointer type */
functor_type* f =
static_cast<functor_type*>(out_buffer.obj_ptr);
delete f;
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
} else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
@ -406,9 +384,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
out_buffer.const_obj_ptr = &typeid(functor_type);
return;
default:
@ -463,9 +439,6 @@ namespace boost {
// Get back to the original pointer type
functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
out_buffer.obj_ptr = new_f;
} else if (op == move_functor_tag) {
out_buffer.obj_ptr = in_buffer.obj_ptr;
in_buffer.obj_ptr = 0;
} else if (op == destroy_functor_tag) {
/* Cast from the void pointer to the functor_wrapper_type */
functor_wrapper_type* victim =
@ -474,17 +447,13 @@ namespace boost {
wrapper_allocator.destroy(victim);
wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
} else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
@ -509,9 +478,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
out_buffer.const_obj_ptr = &typeid(functor_type);
return;
default:
@ -619,7 +586,7 @@ public:
detail::function::function_buffer type;
vtable->manager(functor, type, detail::function::get_functor_type_tag);
return *type.type.type;
return *static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(type.const_obj_ptr);
}
template<typename Functor>
@ -628,9 +595,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
type_result.const_obj_ptr = &typeid(Functor);
vtable->manager(functor, type_result,
detail::function::check_functor_type_tag);
return static_cast<Functor*>(type_result.obj_ptr);
@ -646,9 +611,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
type_result.const_obj_ptr = &typeid(Functor);
vtable->manager(functor, type_result,
detail::function::check_functor_type_tag);
// GCC 2.95.3 gets the CV qualifiers wrong here, so we

View File

@ -1,70 +0,0 @@
// Boost.Function library
// Copyright (C) Douglas Gregor 2008
//
// Use, modification and distribution is subject to the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_FUNCTION_FWD_HPP
#define BOOST_FUNCTION_FWD_HPP
#include <boost/config.hpp>
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
// Work around a compiler bug.
// boost::python::objects::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace objects {
class function;
}}}
#endif
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif
namespace boost {
class bad_function_call;
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
// Preferred syntax
template<typename Signature> class function;
template<typename Signature>
inline void swap(function<Signature>& f1, function<Signature>& f2)
{
f1.swap(f2);
}
#endif // have partial specialization
// Portable syntax
template<typename R> class function0;
template<typename R, typename T1> class function1;
template<typename R, typename T1, typename T2> class function2;
template<typename R, typename T1, typename T2, typename T3> class function3;
template<typename R, typename T1, typename T2, typename T3, typename T4>
class function4;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5>
class function5;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
class function6;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
class function7;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
class function8;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
class function9;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
class function10;
}
#endif

View File

@ -516,9 +516,11 @@ namespace boost {
function_buffer& functor, function_obj_ref_tag)
{
if (!boost::detail::function::has_empty_target(f.get_pointer())) {
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
// DPG TBD: We might need to detect constness of
// FunctionObj to assign into obj_ptr or const_obj_ptr to
// be truly legit, but no platform in existence makes
// const void* different from void*.
functor.const_obj_ptr = f.get_pointer();
return true;
} else {
return false;
@ -727,10 +729,9 @@ namespace boost {
if (&other == this)
return;
BOOST_FUNCTION_FUNCTION tmp;
tmp.move_assign(*this);
this->move_assign(other);
other.move_assign(tmp);
BOOST_FUNCTION_FUNCTION tmp = *this;
*this = other;
other = tmp;
}
// Clear out a target, if there is one
@ -785,33 +786,6 @@ namespace boost {
if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable;
else vtable = 0;
}
// Moves the value from the specified argument to *this. If the argument
// has its function object allocated on the heap, move_assign will pass
// its buffer to *this, and set the argument's buffer pointer to NULL.
void move_assign(BOOST_FUNCTION_FUNCTION& f)
{
if (&f == this)
return;
#if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
if (!f.empty()) {
this->vtable = f.vtable;
f.vtable->manager(f.functor, this->functor,
boost::detail::function::move_functor_tag);
f.vtable = 0;
#if !defined(BOOST_NO_EXCEPTIONS)
} else {
clear();
}
} catch (...) {
vtable = 0;
throw;
}
#endif
}
};
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>

View File

@ -1,45 +0,0 @@
// Boost.Function library - Typeof support
// Copyright (C) Douglas Gregor 2008
//
// Use, modification and distribution is subject to the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_FUNCTION_TYPEOF_HPP
#define BOOST_FUNCTION_TYPEOF_HPP
#include <boost/function/function_fwd.hpp>
#include <boost/typeof/typeof.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TYPE(boost::bad_function_call)
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function, (typename))
#endif
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function0, (typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function1, (typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function2, (typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function3,
(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function4,
(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function5,
(typename)(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function6,
(typename)(typename)(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function7,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function8,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function9,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function10,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename)(typename)(typename))
#endif

View File

@ -58,9 +58,6 @@ import testing ;
[ run libs/function/test/contains2_test.cpp : : : : ]
[ run libs/function/test/nothrow_swap.cpp : : : : ]
[ compile libs/function/test/function_typeof_test.cpp ]
;
}

View File

@ -88,15 +88,6 @@ static void target_test()
BOOST_CHECK(!f.target<int (*)()>());
BOOST_CHECK(f.target<Seventeen>());
BOOST_CHECK(f.target<Seventeen>() == &this_seventeen);
const Seventeen const_seventeen = this_seventeen;
f = boost::ref(const_seventeen);
BOOST_CHECK(!f.target<int (*)()>());
BOOST_CHECK(f.target<const Seventeen>());
BOOST_CHECK(f.target<const Seventeen>() == &const_seventeen);
BOOST_CHECK(f.target<const volatile Seventeen>());
BOOST_CHECK(!f.target<Seventeen>());
BOOST_CHECK(!f.target<volatile Seventeen>());
}
static void equal_test()

View File

@ -636,54 +636,6 @@ test_ref()
}
}
static unsigned construction_count = 0;
static unsigned destruction_count = 0;
struct MySmallFunctor {
MySmallFunctor() { ++construction_count; }
MySmallFunctor(const MySmallFunctor &) { ++construction_count; }
~MySmallFunctor() { ++destruction_count; }
int operator()() { return 0; }
};
struct MyLargeFunctor {
MyLargeFunctor() { ++construction_count; }
MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; }
~MyLargeFunctor() { ++destruction_count; }
int operator()() { return 0; }
float data[128];
};
void test_construct_destroy_count()
{
{
boost::function0<int> f;
boost::function0<int> g;
f = MySmallFunctor();
g = MySmallFunctor();
f.swap(g);
}
// MySmallFunctor objects should be constructed as many times as
// they are destroyed.
BOOST_CHECK(construction_count == destruction_count);
construction_count = 0;
destruction_count = 0;
{
boost::function0<int> f;
boost::function0<int> g;
f = MyLargeFunctor();
g = MyLargeFunctor();
f.swap(g);
}
// MyLargeFunctor objects should be constructed as many times as
// they are destroyed.
BOOST_CHECK(construction_count == destruction_count);
}
int test_main(int, char* [])
{
test_zero_args();
@ -692,6 +644,5 @@ int test_main(int, char* [])
test_emptiness();
test_member_functions();
test_ref();
test_construct_destroy_count();
return 0;
}

View File

@ -1,18 +0,0 @@
// Boost.Function library
// Copyright Douglas Gregor 2008. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#include <boost/function/function_typeof.hpp>
#include <boost/function.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
void f(boost::function0<void> f, boost::function0<void> g)
{
BOOST_STATIC_ASSERT((boost::is_same<boost::function0<void>, BOOST_TYPEOF(f = g)>::value));
}

View File

@ -1,60 +0,0 @@
// Boost.Function library
// Copyright Douglas Gregor 2008. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#include <boost/test/minimal.hpp>
#include <boost/function.hpp>
struct tried_to_copy { };
struct MaybeThrowOnCopy {
MaybeThrowOnCopy(int value = 0) : value(value) { }
MaybeThrowOnCopy(const MaybeThrowOnCopy& other) : value(other.value) {
if (throwOnCopy)
throw tried_to_copy();
}
MaybeThrowOnCopy& operator=(const MaybeThrowOnCopy& other) {
if (throwOnCopy)
throw tried_to_copy();
value = other.value;
return *this;
}
int operator()() { return value; }
int value;
// Make sure that this function object doesn't trigger the
// small-object optimization in Function.
float padding[100];
static bool throwOnCopy;
};
bool MaybeThrowOnCopy::throwOnCopy = false;
int test_main(int, char* [])
{
boost::function0<int> f;
boost::function0<int> g;
MaybeThrowOnCopy::throwOnCopy = false;
f = MaybeThrowOnCopy(1);
g = MaybeThrowOnCopy(2);
BOOST_CHECK(f() == 1);
BOOST_CHECK(g() == 2);
MaybeThrowOnCopy::throwOnCopy = true;
f.swap(g);
BOOST_CHECK(f() == 2);
BOOST_CHECK(g() == 1);
return 0;
}