function_base.hpp:

function_template.hpp:
  - Removed implementation based on virtual functions. Such an implementation
    can't meet exception safety requirements made by the manager/invoker
    version.


[SVN r11726]
This commit is contained in:
Douglas Gregor
2001-11-19 14:52:04 +00:00
parent dd76ed757b
commit 3f13d39604
2 changed files with 10 additions and 368 deletions

View File

@ -138,7 +138,6 @@ namespace boost {
ptr_or_obj_tag>::type type; ptr_or_obj_tag>::type type;
}; };
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
/** /**
* The functor_manager class contains a static function "manage" which * The functor_manager class contains a static function "manage" which
* can clone or destroy the given function/function object pointer. * can clone or destroy the given function/function object pointer.
@ -232,7 +231,6 @@ namespace boost {
return manager(functor_ptr, op, tag_type()); return manager(functor_ptr, op, tag_type());
} }
}; };
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
// value=1 if the given type is not "unusable" // value=1 if the given type is not "unusable"
template<typename T> template<typename T>
@ -278,16 +276,6 @@ namespace boost {
*/ */
class function_base class function_base
{ {
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
public:
function_base() : impl(0) {}
bool empty() const { return impl == 0; }
protected:
void* impl; // Derived class is responsible for knowing the real type
#else
public: public:
function_base() : manager(0), functor(static_cast<void*>(0)) {} function_base() : manager(0), functor(static_cast<void*>(0)) {}
@ -299,7 +287,6 @@ namespace boost {
detail::function::any_pointer, detail::function::any_pointer,
detail::function::functor_manager_operation_type); detail::function::functor_manager_operation_type);
detail::function::any_pointer functor; detail::function::any_pointer functor;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
private: private:
struct dummy { struct dummy {

View File

@ -13,21 +13,12 @@
// For more information, see http://www.boost.org // For more information, see http://www.boost.org
/* 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 <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
// Zero-initialize the "invoker" member of the functionN object.
// The invoker member only exists when we aren't using the virtual
// function implementation
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
# define BOOST_FUNCTION_INIT
#else
# define BOOST_FUNCTION_INIT , invoker(0)
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
// Type of the default allocator // Type of the default allocator
#ifndef BOOST_NO_STD_ALLOCATOR #ifndef BOOST_NO_STD_ALLOCATOR
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base> # define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
@ -38,161 +29,28 @@
namespace boost { namespace boost {
namespace detail { namespace detail {
namespace function { namespace function {
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
struct BOOST_FUNCTION_INVOKER_BASE
{
virtual ~BOOST_FUNCTION_INVOKER_BASE() {}
virtual R call(BOOST_FUNCTION_PARMS) const = 0;
virtual BOOST_FUNCTION_INVOKER_BASE* clone() const = 0;
virtual void destroy(BOOST_FUNCTION_INVOKER_BASE*) = 0;
};
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
template< template<
typename FunctionPtr, typename FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS BOOST_FUNCTION_TEMPLATE_PARMS
> >
struct BOOST_FUNCTION_FUNCTION_INVOKER struct BOOST_FUNCTION_FUNCTION_INVOKER
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
: public BOOST_FUNCTION_INVOKER_BASE<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
{ {
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
explicit BOOST_FUNCTION_FUNCTION_INVOKER(FunctionPtr f) :
function_ptr(f) {}
virtual R call(BOOST_FUNCTION_PARMS) const
{
return function_ptr(BOOST_FUNCTION_ARGS);
}
virtual BOOST_FUNCTION_FUNCTION_INVOKER* clone() const
{
# ifdef BOOST_NO_STD_ALLOCATOR
return new BOOST_FUNCTION_FUNCTION_INVOKER(function_ptr);
# else
typedef typename Allocator::
template rebind<BOOST_FUNCTION_FUNCTION_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
allocator.construct(copy, *this);
return static_cast<BOOST_FUNCTION_FUNCTION_INVOKER*>(copy);
# endif // BOOST_NO_STD_ALLOCATOR
}
virtual void destroy(BOOST_FUNCTION_INVOKER_BASE<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>* p)
{
# ifdef BOOST_NO_STD_ALLOCATOR
delete p;
# else
BOOST_FUNCTION_FUNCTION_INVOKER* victim =
dynamic_cast<BOOST_FUNCTION_FUNCTION_INVOKER*>(p);
typedef typename Allocator::
template rebind<BOOST_FUNCTION_FUNCTION_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
allocator.destroy(victim);
allocator.deallocate(victim, 1);
# endif // BOOST_NO_STD_ALLOCATOR
}
private:
mutable FunctionPtr function_ptr;
#else
static R invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA static R invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS) BOOST_FUNCTION_PARMS)
{ {
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr); FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
return f(BOOST_FUNCTION_ARGS); return f(BOOST_FUNCTION_ARGS);
} }
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}; };
template< template<
typename FunctionPtr, typename FunctionPtr,
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS BOOST_FUNCTION_TEMPLATE_PARMS
> >
struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
: public BOOST_FUNCTION_INVOKER_BASE<
unusable BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
{ {
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
explicit BOOST_FUNCTION_VOID_FUNCTION_INVOKER(FunctionPtr f) :
function_ptr(f) {}
virtual unusable call(BOOST_FUNCTION_PARMS) const
{
function_ptr(BOOST_FUNCTION_ARGS);
return unusable();
}
virtual BOOST_FUNCTION_VOID_FUNCTION_INVOKER* clone() const
{
# ifdef BOOST_NO_STD_ALLOCATOR
return new BOOST_FUNCTION_VOID_FUNCTION_INVOKER(function_ptr);
# else
typedef typename Allocator::
template rebind<BOOST_FUNCTION_VOID_FUNCTION_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
allocator.construct(copy, *this);
return static_cast<BOOST_FUNCTION_VOID_FUNCTION_INVOKER*>(copy);
# endif // BOOST_NO_STD_ALLOCATOR
}
virtual void destroy(BOOST_FUNCTION_INVOKER_BASE<
unusable BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>* p)
{
# ifdef BOOST_NO_STD_ALLOCATOR
delete p;
# else
BOOST_FUNCTION_VOID_FUNCTION_INVOKER* victim =
dynamic_cast<BOOST_FUNCTION_VOID_FUNCTION_INVOKER*>(p);
typedef typename Allocator::
template rebind<BOOST_FUNCTION_VOID_FUNCTION_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
allocator.destroy(victim);
allocator.deallocate(victim, 1);
# endif // BOOST_NO_STD_ALLOCATOR
}
private:
mutable FunctionPtr function_ptr;
# else
static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS) BOOST_FUNCTION_PARMS)
@ -201,76 +59,15 @@ namespace boost {
f(BOOST_FUNCTION_ARGS); f(BOOST_FUNCTION_ARGS);
return unusable(); return unusable();
} }
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}; };
template< template<
typename FunctionObj, typename FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS BOOST_FUNCTION_TEMPLATE_PARMS
> >
struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
: public BOOST_FUNCTION_INVOKER_BASE<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
{ {
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
explicit BOOST_FUNCTION_FUNCTION_OBJ_INVOKER(const FunctionObj& f) :
function_obj(f) {}
virtual R call(BOOST_FUNCTION_PARMS) const
{
return function_obj(BOOST_FUNCTION_ARGS);
}
virtual BOOST_FUNCTION_FUNCTION_OBJ_INVOKER* clone() const
{
#ifdef BOOST_NO_STD_ALLOCATOR
return new BOOST_FUNCTION_FUNCTION_OBJ_INVOKER(function_obj);
#else
typedef typename Allocator::
template rebind<BOOST_FUNCTION_FUNCTION_OBJ_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
allocator.construct(copy, *this);
return static_cast<BOOST_FUNCTION_FUNCTION_OBJ_INVOKER*>(copy);
#endif // BOOST_NO_STD_ALLOCATOR
}
virtual void destroy(BOOST_FUNCTION_INVOKER_BASE<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>* p)
{
#ifdef BOOST_NO_STD_ALLOCATOR
delete p;
#else
BOOST_FUNCTION_FUNCTION_OBJ_INVOKER* victim =
dynamic_cast<BOOST_FUNCTION_FUNCTION_OBJ_INVOKER*>(p);
typedef typename Allocator::
template rebind<BOOST_FUNCTION_FUNCTION_OBJ_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
allocator.destroy(victim);
allocator.deallocate(victim, 1);
#endif // BOOST_NO_STD_ALLOCATOR
}
private:
mutable FunctionObj function_obj;
#else
static R invoke(any_pointer function_obj_ptr BOOST_FUNCTION_COMMA static R invoke(any_pointer function_obj_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS) BOOST_FUNCTION_PARMS)
@ -278,77 +75,15 @@ namespace boost {
FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr); FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
return (*f)(BOOST_FUNCTION_ARGS); return (*f)(BOOST_FUNCTION_ARGS);
} }
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}; };
template< template<
typename FunctionObj, typename FunctionObj,
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS BOOST_FUNCTION_TEMPLATE_PARMS
> >
struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
: public BOOST_FUNCTION_INVOKER_BASE<
unusable BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
{ {
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
explicit BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER(const FunctionObj& f)
: function_obj(f) {}
virtual unusable call(BOOST_FUNCTION_PARMS) const
{
function_obj(BOOST_FUNCTION_ARGS);
return unusable();
}
virtual BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER* clone() const
{
# ifdef BOOST_NO_STD_ALLOCATOR
return new BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER(function_obj);
# else
typedef typename Allocator::
template rebind<BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
allocator.construct(copy, *this);
return static_cast<BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER*>(copy);
# endif // BOOST_NO_STD_ALLOCATOR
}
virtual void destroy(BOOST_FUNCTION_INVOKER_BASE<
unusable BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>* p)
{
# ifdef BOOST_NO_STD_ALLOCATOR
delete p;
# else
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER* victim =
dynamic_cast<BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER*>(p);
typedef typename Allocator::
template rebind<BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
allocator.destroy(victim);
allocator.deallocate(victim, 1);
# endif // BOOST_NO_STD_ALLOCATOR
}
private:
mutable FunctionObj function_obj;
# else
static unusable invoke(any_pointer function_obj_ptr static unusable invoke(any_pointer function_obj_ptr
BOOST_FUNCTION_COMMA BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS) BOOST_FUNCTION_PARMS)
@ -358,7 +93,6 @@ namespace boost {
(*f)(BOOST_FUNCTION_ARGS); (*f)(BOOST_FUNCTION_ARGS);
return unusable(); return unusable();
} }
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}; };
template< template<
@ -372,17 +106,11 @@ namespace boost {
typedef typename IF<(is_void<R>::value), typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_INVOKER< BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
FunctionPtr, FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS BOOST_FUNCTION_TEMPLATE_ARGS
>, >,
BOOST_FUNCTION_FUNCTION_INVOKER< BOOST_FUNCTION_FUNCTION_INVOKER<
FunctionPtr, FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS BOOST_FUNCTION_TEMPLATE_ARGS
> >
@ -400,17 +128,11 @@ namespace boost {
typedef typename IF<(is_void<R>::value), typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
FunctionObj, FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS BOOST_FUNCTION_TEMPLATE_ARGS
>, >,
BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
FunctionObj, FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS BOOST_FUNCTION_TEMPLATE_ARGS
> >
@ -444,20 +166,10 @@ namespace boost {
typedef Allocator allocator_type; typedef Allocator allocator_type;
typedef BOOST_FUNCTION_FUNCTION self_type; typedef BOOST_FUNCTION_FUNCTION self_type;
private: BOOST_FUNCTION_FUNCTION() : function_base(), Mixin(), invoker(0) {}
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typedef detail::function::BOOST_FUNCTION_INVOKER_BASE<
result_type BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
impl_type;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
public:
BOOST_FUNCTION_FUNCTION() : function_base(), Mixin() BOOST_FUNCTION_INIT {}
explicit BOOST_FUNCTION_FUNCTION(const Mixin& m) : explicit BOOST_FUNCTION_FUNCTION(const Mixin& m) :
function_base(), Mixin(m) BOOST_FUNCTION_INIT function_base(), Mixin(m), invoker(0)
{ {
} }
@ -465,14 +177,14 @@ namespace boost {
// one with a default parameter. // one with a default parameter.
template<typename Functor> template<typename Functor>
BOOST_FUNCTION_FUNCTION(const Functor& f) : BOOST_FUNCTION_FUNCTION(const Functor& f) :
function_base(), Mixin() BOOST_FUNCTION_INIT function_base(), Mixin(), invoker(0)
{ {
this->assign_to(f); this->assign_to(f);
} }
template<typename Functor> template<typename Functor>
BOOST_FUNCTION_FUNCTION(const Functor& f, const Mixin& m) : BOOST_FUNCTION_FUNCTION(const Functor& f, const Mixin& m) :
function_base(), Mixin(m) BOOST_FUNCTION_INIT function_base(), Mixin(m), invoker(0)
{ {
this->assign_to(f); this->assign_to(f);
} }
@ -480,15 +192,14 @@ namespace boost {
#ifdef __BORLANDC__ #ifdef __BORLANDC__
template<typename Functor> template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor* f, const Mixin& m = Mixin()) : BOOST_FUNCTION_FUNCTION(Functor* f, const Mixin& m = Mixin()) :
function_base(), Mixin(m) BOOST_FUNCTION_INIT function_base(), Mixin(m), invoker(0)
{ {
this->assign_to(f); this->assign_to(f);
} }
#endif // __BORLANDC__ #endif // __BORLANDC__
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) :
function_base(), Mixin(static_cast<const Mixin&>(f)) function_base(), Mixin(static_cast<const Mixin&>(f)), invoker(0)
BOOST_FUNCTION_INIT
{ {
this->assign_to_own(f); this->assign_to_own(f);
} }
@ -502,13 +213,8 @@ namespace boost {
policy_type policy; policy_type policy;
policy.precall(this); policy.precall(this);
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
const impl_type* i = reinterpret_cast<const impl_type*>(impl);
result_type result = i->call(BOOST_FUNCTION_ARGS);
#else
result_type result = invoker(functor BOOST_FUNCTION_COMMA result_type result = invoker(functor BOOST_FUNCTION_COMMA
BOOST_FUNCTION_ARGS); BOOST_FUNCTION_ARGS);
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
policy.postcall(this); policy.postcall(this);
return result; return result;
@ -573,46 +279,29 @@ namespace boost {
if (&other == this) if (&other == this)
return; return;
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
std::swap(manager, other.manager); std::swap(manager, other.manager);
std::swap(functor, other.functor); std::swap(functor, other.functor);
std::swap(invoker, other.invoker); std::swap(invoker, other.invoker);
#else std::swap(static_cast<Mixin&>(*this), static_cast<Mixin&>(other));
std::swap(impl, other.impl);
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
std::swap(static_cast<Mixin&>(*this),static_cast<Mixin&>(other));
} }
// Clear out a target, if there is one // Clear out a target, if there is one
void clear() void clear()
{ {
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
if (impl) {
impl_type* i = reinterpret_cast<impl_type*>(impl);
i->destroy(i);
impl = 0;
}
#else
if (manager) if (manager)
functor = manager(functor, detail::function::destroy_functor); functor = manager(functor, detail::function::destroy_functor);
manager = 0; manager = 0;
invoker = 0; invoker = 0;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
} }
private: private:
void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
{ {
if (!f.empty()) { if (!f.empty()) {
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
impl_type* other_impl = reinterpret_cast<impl_type*>(f.impl);
impl = static_cast<void*>(other_impl->clone());
# else
invoker = f.invoker; invoker = f.invoker;
manager = f.manager; manager = f.manager;
functor = f.manager(f.functor, detail::function::clone_functor); functor = f.manager(f.functor, detail::function::clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
} }
} }
@ -643,21 +332,6 @@ namespace boost {
>::type >::type
invoker_type; invoker_type;
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
# ifdef BOOST_NO_STD_ALLOCATOR
impl_type* i = new invoker_type(f);
# else
typedef typename Allocator::template rebind<invoker_type>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
new (copy) invoker_type(f);
impl_type* i = static_cast<impl_type*>(copy);
# endif // BOOST_NO_STD_ALLOCATOR
impl = static_cast<void*>(i);
# else
invoker = &invoker_type::invoke; invoker = &invoker_type::invoke;
manager = &detail::function::functor_manager<FunctionPtr, manager = &detail::function::functor_manager<FunctionPtr,
Allocator>::manage; Allocator>::manage;
@ -665,7 +339,6 @@ namespace boost {
reinterpret_cast<void (*)()>(f) reinterpret_cast<void (*)()>(f)
), ),
detail::function::clone_functor); detail::function::clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
} }
} }
@ -682,38 +355,20 @@ namespace boost {
>::type >::type
invoker_type; invoker_type;
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
# ifdef BOOST_NO_STD_ALLOCATOR
impl_type* i = new invoker_type(f);
# else
typedef typename Allocator::template rebind<invoker_type>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
allocator_type allocator;
pointer_type copy = allocator.allocate(1);
new (copy) invoker_type(f);
impl_type* i = static_cast<impl_type*>(copy);
# endif // BOOST_NO_STD_ALLOCATOR
impl = static_cast<void*>(i);
# else
invoker = &invoker_type::invoke; invoker = &invoker_type::invoke;
manager = &detail::function::functor_manager<FunctionObj, manager = &detail::function::functor_manager<FunctionObj,
Allocator>::manage; Allocator>::manage;
functor = functor =
manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)), manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)),
detail::function::clone_functor); detail::function::clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
} }
} }
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typedef result_type (*invoker_type)(detail::function::any_pointer typedef result_type (*invoker_type)(detail::function::any_pointer
BOOST_FUNCTION_COMMA BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS); BOOST_FUNCTION_TEMPLATE_ARGS);
invoker_type invoker; invoker_type invoker;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}; };
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS , template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
@ -739,4 +394,4 @@ namespace boost {
// Cleanup after ourselves... // Cleanup after ourselves...
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR #undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
#undef BOOST_FUNCTION_INIT