Compare commits

..

18 Commits

Author SHA1 Message Date
cb1a2944fd bcbboost branch rebased on current release
[SVN r49389]
2008-10-19 14:43:01 +00:00
587658b047 Merge Boost.Function fixes from trunk
[SVN r49361]
2008-10-16 13:21:50 +00:00
29ef7ae490 Patches for Codegear C++ Builder 2009
[SVN r48981]
2008-09-27 08:59:20 +00:00
83309a36c7 Merge Boost.Function from the trunk
[SVN r47422]
2008-07-14 18:32:29 +00:00
bfdb5b161d Merged fixes for Function, Signals, and MPI from trunk. See #1499, see #1416, see #1486
[SVN r42031]
2007-12-14 14:48:14 +00:00
c4539395fe Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
d8c93cdc8d Merge from trunk
[SVN r39768]
2007-10-07 20:10:53 +00:00
6147e7ddcc Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
5073f4fd97 Branch for CodeGear (Borland) specific fixes
[SVN r39356]
2007-09-17 20:28:43 +00:00
1b60e82b2f This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
7581949360 Patches from Trac #583.
[SVN r37846]
2007-06-01 16:12:08 +00:00
0b2aeda226 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
2ecd62c612 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
47033bd162 Fix inspection problems
[SVN r35827]
2006-11-03 19:41:10 +00:00
c7d5016022 Eliminate MSVC 8.0 warning
[SVN r35588]
2006-10-13 14:29:56 +00:00
d92355cca2 Suppress annoying MSVC warnings
[SVN r35424]
2006-09-29 17:23:28 +00:00
0123f84bff Suppress annoying MSVC warnings
[SVN r35423]
2006-09-29 17:23:17 +00:00
0207da8008 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
8 changed files with 83 additions and 165 deletions

View File

@ -6,10 +6,5 @@
project boost/doc ; project boost/doc ;
import boostbook : boostbook ; import boostbook : boostbook ;
boostbook function-doc boostbook function-doc : function.xml ;
:
function.xml
:
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;

View File

@ -35,12 +35,12 @@ form to use for your compiler.
<row> <row>
<entry> <entry>
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem><simpara>GNU C++ 2.95.x, 3.0.x and later versions</simpara></listitem> <listitem><simpara>GNU C++ 2.95.x, 3.0.x, 3.1.x</simpara></listitem>
<listitem><simpara>Comeau C++ 4.2.45.2</simpara></listitem> <listitem><simpara>Comeau C++ 4.2.45.2</simpara></listitem>
<listitem><simpara>SGI MIPSpro 7.3.0</simpara></listitem> <listitem><simpara>SGI MIPSpro 7.3.0</simpara></listitem>
<listitem><simpara>Intel C++ 5.0, 6.0</simpara></listitem> <listitem><simpara>Intel C++ 5.0, 6.0</simpara></listitem>
<listitem><simpara>Compaq's cxx 6.2</simpara></listitem> <listitem><simpara>Compaq's cxx 6.2</simpara></listitem>
<listitem><simpara>Microsoft Visual C++ 7.1 and later versions</simpara></listitem> <listitem><simpara>Microsoft Visual C++ 7.1</simpara></listitem>
</itemizedlist> </itemizedlist>
</entry> </entry>
<entry> <entry>

View File

@ -15,12 +15,9 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <new> #include <new>
#include <typeinfo>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/integer.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_volatile.hpp> #include <boost/type_traits/is_volatile.hpp>
@ -45,7 +42,7 @@
#endif #endif
// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info. // Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
#ifdef BOOST_NO_STD_TYPEINFO #ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE
// Embedded VC++ does not have type_info in namespace std // Embedded VC++ does not have type_info in namespace std
# define BOOST_FUNCTION_STD_NS # define BOOST_FUNCTION_STD_NS
#else #else
@ -54,9 +51,7 @@
// Borrowed from Boost.Python library: determines the cases where we // Borrowed from Boost.Python library: determines the cases where we
// need to use std::type_info::name to compare instead of operator==. // need to use std::type_info::name to compare instead of operator==.
#if defined( BOOST_NO_TYPEID ) # if (defined(__GNUC__) && __GNUC__ >= 3) \
# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
#elif (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \ || defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips)) || ( defined(__sgi) && defined(__host_mips))
# include <cstring> # include <cstring>
@ -105,7 +100,7 @@ namespace boost {
// For pointers to std::type_info objects // For pointers to std::type_info objects
struct type_t { struct type_t {
// (get_functor_type_tag, check_functor_type_tag). // (get_functor_type_tag, check_functor_type_tag).
const detail::sp_typeinfo* type; const BOOST_FUNCTION_STD_NS::type_info* type;
// Whether the type is const-qualified. // Whether the type is const-qualified.
bool const_qualified; bool const_qualified;
@ -217,12 +212,12 @@ namespace boost {
case check_functor_type_tag: case check_functor_type_tag:
{ {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
// Check whether we have the same type. We can add // Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away. // cv-qualifiers, but we can't take them away.
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F)) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
&& (!in_buffer.obj_ref.is_const_qualified && (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified) || out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified && (!in_buffer.obj_ref.is_volatile_qualified
@ -234,7 +229,7 @@ namespace boost {
return; return;
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(F); out_buffer.type.type = &typeid(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified; 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.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
return; return;
@ -264,12 +259,6 @@ namespace boost {
A(a) A(a)
{ {
} }
functor_wrapper(const functor_wrapper& f) :
F(static_cast<const F&>(f)),
A(static_cast<const A&>(f))
{
}
}; };
/** /**
@ -294,14 +283,14 @@ namespace boost {
} else if (op == destroy_functor_tag) } else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0; out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) { else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr; out_buffer.obj_ptr = &in_buffer.func_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -324,14 +313,14 @@ namespace boost {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor(); reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.data; out_buffer.obj_ptr = &in_buffer.data;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -383,14 +372,14 @@ namespace boost {
delete f; delete f;
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr; out_buffer.obj_ptr = in_buffer.obj_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -425,7 +414,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type; typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) { switch (op) {
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
return; return;
@ -494,14 +483,14 @@ namespace boost {
wrapper_allocator.deallocate(victim,1); wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr; out_buffer.obj_ptr = in_buffer.obj_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -528,7 +517,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type; typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) { switch (op) {
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
return; return;
@ -629,14 +618,14 @@ public:
/** Determine if the function is empty (i.e., has no target). */ /** Determine if the function is empty (i.e., has no target). */
bool empty() const { return !vtable; } bool empty() const { return !vtable; }
/** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void) /** Retrieve the type of the stored function object, or typeid(void)
if this is empty. */ if this is empty. */
const detail::sp_typeinfo& target_type() const const BOOST_FUNCTION_STD_NS::type_info& target_type() const
{ {
if (!vtable) return BOOST_SP_TYPEID(void); if (!vtable) return typeid(void);
detail::function::function_buffer type; detail::function::function_buffer type;
get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); vtable->manager(functor, type, detail::function::get_functor_type_tag);
return *type.type.type; return *type.type.type;
} }
@ -646,10 +635,10 @@ public:
if (!vtable) return 0; if (!vtable) return 0;
detail::function::function_buffer type_result; detail::function::function_buffer type_result;
type_result.type.type = &BOOST_SP_TYPEID(Functor); type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = is_const<Functor>::value; type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value; type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result, vtable->manager(functor, type_result,
detail::function::check_functor_type_tag); detail::function::check_functor_type_tag);
return static_cast<Functor*>(type_result.obj_ptr); return static_cast<Functor*>(type_result.obj_ptr);
} }
@ -664,10 +653,10 @@ public:
if (!vtable) return 0; if (!vtable) return 0;
detail::function::function_buffer type_result; detail::function::function_buffer type_result;
type_result.type.type = &BOOST_SP_TYPEID(Functor); type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = true; type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value; type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result, vtable->manager(functor, type_result,
detail::function::check_functor_type_tag); detail::function::check_functor_type_tag);
// GCC 2.95.3 gets the CV qualifiers wrong here, so we // GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do. // can't do the static_cast that we should do.
@ -713,15 +702,6 @@ public:
#endif #endif
public: // should be protected, but GCC 2.95.3 will fail to allow access public: // should be protected, but GCC 2.95.3 will fail to allow access
detail::function::vtable_base* get_vtable() const {
return reinterpret_cast<detail::function::vtable_base*>(
reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
}
bool has_trivial_copy_and_destroy() const {
return reinterpret_cast<std::size_t>(vtable) & 0x01;
}
detail::function::vtable_base* vtable; detail::function::vtable_base* vtable;
mutable detail::function::function_buffer functor; mutable detail::function::function_buffer functor;
}; };
@ -897,8 +877,4 @@ namespace detail {
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
#undef BOOST_FUNCTION_COMPARE_TYPE_ID #undef BOOST_FUNCTION_COMPARE_TYPE_ID
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
#endif // BOOST_FUNCTION_BASE_HEADER #endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -21,7 +21,7 @@ namespace boost { namespace python { namespace objects {
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ #if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \ || defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540) || !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX # define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif #endif

View File

@ -11,7 +11,6 @@
// Note: this header is a header template and must NOT have multiple-inclusion // Note: this header is a header template and must NOT have multiple-inclusion
// protection. // protection.
#include <boost/function/detail/prologue.hpp> #include <boost/function/detail/prologue.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning( push ) # pragma warning( push )
@ -625,10 +624,14 @@ namespace boost {
assign_to(const reference_wrapper<FunctionObj>& f, assign_to(const reference_wrapper<FunctionObj>& f,
function_buffer& functor, function_obj_ref_tag) function_buffer& functor, function_obj_ref_tag)
{ {
functor.obj_ref.obj_ptr = (void *)f.get_pointer(); if (!boost::detail::function::has_empty_target(f.get_pointer())) {
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value; functor.obj_ref.obj_ptr = (void *)f.get_pointer();
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value; functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
return true; functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
return true;
} else {
return false;
}
} }
template<typename FunctionObj,typename Allocator> template<typename FunctionObj,typename Allocator>
bool bool
@ -675,11 +678,6 @@ namespace boost {
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
vtable_type; vtable_type;
vtable_type* get_vtable() const {
return reinterpret_cast<vtable_type*>(
reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
}
struct clear_type {}; struct clear_type {};
public: public:
@ -759,7 +757,7 @@ namespace boost {
if (this->empty()) if (this->empty())
boost::throw_exception(bad_function_call()); boost::throw_exception(bad_function_call());
return get_vtable()->invoker return static_cast<vtable_type*>(vtable)->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
} }
#else #else
@ -783,26 +781,24 @@ namespace boost {
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{ {
this->clear(); this->clear();
BOOST_TRY { try {
this->assign_to(f); this->assign_to(f);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
return *this; return *this;
} }
template<typename Functor,typename Allocator> template<typename Functor,typename Allocator>
void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
{ {
this->clear(); this->clear();
BOOST_TRY{ try {
this->assign_to_a(f,a); this->assign_to_a(f,a);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
} }
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
@ -827,13 +823,12 @@ namespace boost {
return *this; return *this;
this->clear(); this->clear();
BOOST_TRY { try {
this->assign_to_own(f); this->assign_to_own(f);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
return *this; return *this;
} }
@ -852,8 +847,7 @@ namespace boost {
void clear() void clear()
{ {
if (vtable) { if (vtable) {
if (!this->has_trivial_copy_and_destroy()) reinterpret_cast<vtable_type*>(vtable)->clear(this->functor);
get_vtable()->clear(this->functor);
vtable = 0; vtable = 0;
} }
} }
@ -882,11 +876,8 @@ namespace boost {
{ {
if (!f.empty()) { if (!f.empty()) {
this->vtable = f.vtable; this->vtable = f.vtable;
if (this->has_trivial_copy_and_destroy()) f.vtable->manager(f.functor, this->functor,
this->functor = f.functor; boost::detail::function::clone_functor_tag);
else
get_vtable()->base.manager(f.functor, this->functor,
boost::detail::function::clone_functor_tag);
} }
} }
@ -912,15 +903,8 @@ namespace boost {
static vtable_type stored_vtable = static vtable_type stored_vtable =
{ { &manager_type::manage }, &invoker_type::invoke }; { { &manager_type::manage }, &invoker_type::invoke };
if (stored_vtable.assign_to(f, functor)) { if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base;
std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base); else vtable = 0;
if (boost::has_trivial_copy_constructor<Functor>::value &&
boost::has_trivial_destructor<Functor>::value &&
detail::function::function_allows_small_object_optimization<Functor>::value)
value |= (std::size_t)0x01;
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
} else
vtable = 0;
} }
template<typename Functor,typename Allocator> template<typename Functor,typename Allocator>
@ -946,15 +930,8 @@ namespace boost {
static vtable_type stored_vtable = static vtable_type stored_vtable =
{ { &manager_type::manage }, &invoker_type::invoke }; { { &manager_type::manage }, &invoker_type::invoke };
if (stored_vtable.assign_to_a(f, functor, a)) { if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable.base;
std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base); else vtable = 0;
if (boost::has_trivial_copy_constructor<Functor>::value &&
boost::has_trivial_destructor<Functor>::value &&
detail::function::function_allows_small_object_optimization<Functor>::value)
value |= (std::size_t)0x01;
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
} else
vtable = 0;
} }
// Moves the value from the specified argument to *this. If the argument // Moves the value from the specified argument to *this. If the argument
@ -965,23 +942,23 @@ namespace boost {
if (&f == this) if (&f == this)
return; return;
BOOST_TRY { #if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
if (!f.empty()) { if (!f.empty()) {
this->vtable = f.vtable; this->vtable = f.vtable;
if (this->has_trivial_copy_and_destroy()) f.vtable->manager(f.functor, this->functor,
this->functor = f.functor; boost::detail::function::move_functor_tag);
else f.vtable = 0;
get_vtable()->base.manager(f.functor, this->functor, #if !defined(BOOST_NO_EXCEPTIONS)
boost::detail::function::move_functor_tag);
f.vtable = 0;
} else { } else {
clear(); clear();
} }
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END #endif
} }
}; };
@ -1002,14 +979,13 @@ namespace boost {
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
typename BOOST_FUNCTION_FUNCTION< typename BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
inline BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
::operator()(BOOST_FUNCTION_PARMS) const ::operator()(BOOST_FUNCTION_PARMS) const
{ {
if (this->empty()) if (this->empty())
boost::throw_exception(bad_function_call()); boost::throw_exception(bad_function_call());
return get_vtable()->invoker return reinterpret_cast<const vtable_type*>(vtable)->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
} }
#endif #endif

View File

@ -128,10 +128,6 @@ test_main(int, char*[])
BOOST_CHECK(dealloc_count == 0); BOOST_CHECK(dealloc_count == 0);
fv.assign( &do_nothing, std::allocator<int>() ); fv.assign( &do_nothing, std::allocator<int>() );
fv.clear(); fv.clear();
function0<void> fv2;
fv.assign(&do_nothing, std::allocator<int>() );
fv2.assign(fv, std::allocator<int>() );
return 0; return 0;
} }

View File

@ -13,8 +13,8 @@
#include <string> #include <string>
#include <utility> #include <utility>
using boost::function; using namespace boost;
using std::string; using namespace std;
int global_int; int global_int;
@ -525,7 +525,7 @@ test_zero_args()
static void static void
test_one_arg() test_one_arg()
{ {
std::negate<int> neg; negate<int> neg;
function<int (int)> f1(neg); function<int (int)> f1(neg);
BOOST_CHECK(f1(5) == -5); BOOST_CHECK(f1(5) == -5);
@ -607,12 +607,12 @@ struct add_with_throw_on_copy {
add_with_throw_on_copy(const add_with_throw_on_copy&) add_with_throw_on_copy(const add_with_throw_on_copy&)
{ {
throw std::runtime_error("But this CAN'T throw"); throw runtime_error("But this CAN'T throw");
} }
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&) add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
{ {
throw std::runtime_error("But this CAN'T throw"); throw runtime_error("But this CAN'T throw");
} }
}; };
@ -621,38 +621,14 @@ test_ref()
{ {
add_with_throw_on_copy atc; add_with_throw_on_copy atc;
try { try {
boost::function<int (int, int)> f(boost::ref(atc)); boost::function<int (int, int)> f(ref(atc));
BOOST_CHECK(f(1, 3) == 4); BOOST_CHECK(f(1, 3) == 4);
} }
catch(std::runtime_error e) { catch(runtime_error e) {
BOOST_ERROR("Nonthrowing constructor threw an exception"); BOOST_ERROR("Nonthrowing constructor threw an exception");
} }
} }
static void dummy() {}
static void test_empty_ref()
{
boost::function<void()> f1;
boost::function<void()> f2(boost::ref(f1));
try {
f2();
BOOST_ERROR("Exception didn't throw for reference to empty function.");
}
catch(std::runtime_error e) {}
f1 = dummy;
try {
f2();
}
catch(std::runtime_error e) {
BOOST_ERROR("Error calling referenced function.");
}
}
static void test_exception() static void test_exception()
{ {
boost::function<int (int, int)> f; boost::function<int (int, int)> f;
@ -698,7 +674,6 @@ int test_main(int, char* [])
test_emptiness(); test_emptiness();
test_member_functions(); test_member_functions();
test_ref(); test_ref();
test_empty_ref();
test_exception(); test_exception();
test_implicit(); test_implicit();
test_call(); test_call();

View File

@ -15,21 +15,21 @@
#include <boost/lambda/bind.hpp> #include <boost/lambda/bind.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
using namespace std;
using namespace boost;
using namespace boost::lambda;
static unsigned static unsigned
func_impl(int arg1, bool arg2, double arg3) func_impl(int arg1, bool arg2, double arg3)
{ {
using namespace std;
return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3)); return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3));
} }
int test_main(int, char*[]) int test_main(int, char*[])
{ {
using boost::function;
using namespace boost::lambda;
function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2); function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2);
function <unsigned(double)> f2 = boost::lambda::bind(f1, false, _1); function <unsigned(double)> f2 = bind(f1, false, _1);
function <unsigned()> f3 = boost::lambda::bind(f2, 4.0); function <unsigned()> f3 = bind(f2, 4.0);
f3(); f3();