Files
boost_function/include/boost/function/function_template.hpp
Douglas Gregor 1f24873577 The void partial specialization of the function classes has been removed in
favor of a common interface. Regardless of the compiler's capabilities, the
result type of a Boost.Function function object that was declared void will
be "unused". This allows the result of a Boost.Function function object to
be passed as a parameter regardless of whether the function is declared as
returning void. It greatly simplifies the use of Boost.Function objects with
wrapper objects (i.e., when the side effects are important, but the result
isn't: consider binding and composition when calling a std::for_each loop)


[SVN r10491]
2001-07-01 02:17:36 +00:00

786 lines
26 KiB
C++

// Boost.Function library
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
/* Note: this header is a header template and must NOT have multiple-inclusion
protection. */
#include <cassert>
#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
namespace boost {
namespace detail {
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) = 0;
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<
typename FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
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)
{
return function_ptr(BOOST_FUNCTION_ARGS);
}
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:
FunctionPtr function_ptr;
#else
static R invoke(any_pointer function_ptr,
bool BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
return f(BOOST_FUNCTION_ARGS);
}
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
};
template<
typename FunctionPtr,
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
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)
{
function_ptr(BOOST_FUNCTION_ARGS);
return unusable();
}
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:
FunctionPtr function_ptr;
# else
static unusable invoke(any_pointer function_ptr,
bool BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
f(BOOST_FUNCTION_ARGS);
return unusable();
}
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
};
template<
typename FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
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)
{
return function_obj(BOOST_FUNCTION_ARGS);
}
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:
FunctionObj function_obj;
#else
static R invoke(any_pointer function_obj_ptr,
bool is_const BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
if (is_const) {
const FunctionObj* fc = f;
return (*fc)(BOOST_FUNCTION_ARGS);
}
else {
return (*f)(BOOST_FUNCTION_ARGS);
}
}
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
};
template<
typename FunctionObj,
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename Allocator,
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
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)
{
function_obj(BOOST_FUNCTION_ARGS);
return unusable();
}
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:
FunctionObj function_obj;
# else
static unusable invoke(any_pointer function_obj_ptr,
bool is_const BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
if (is_const) {
const FunctionObj* fc = f;
(*fc)(BOOST_FUNCTION_ARGS);
}
else {
(*f)(BOOST_FUNCTION_ARGS);
}
return unusable();
}
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
};
template<
typename FunctionPtr,
typename Allocator,
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
{
typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>,
BOOST_FUNCTION_FUNCTION_INVOKER<
FunctionPtr,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
>::type type;
};
template<
typename FunctionObj,
typename Allocator,
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS
>
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
{
typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>,
BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
FunctionObj,
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
Allocator,
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
>::type type;
};
/* This base class encapsulates the copy behavior of the user-level
functionN classes. The void partial specialization used by compilers
that support partial specialization merely changes the call routines,
so we factor all other behavior here. */
template<
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS,
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
class BOOST_FUNCTION_BASE : public function_base, public Mixin
{
public:
BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
typedef typename function_return_type<R>::type result_type;
typedef Policy policy_type;
typedef Mixin mixin_type;
typedef Allocator allocator_type;
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typedef BOOST_FUNCTION_INVOKER_BASE<
result_type BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>
impl_type;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
// Construct without a target
BOOST_FUNCTION_BASE() : function_base() BOOST_FUNCTION_INIT {}
// Destroy the target, if there is one
~BOOST_FUNCTION_BASE() { clear(); }
void swap(BOOST_FUNCTION_BASE& other)
{
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
std::swap(manager, other.manager);
std::swap(functor, other.functor);
std::swap(invoker, other.invoker);
#else
std::swap(impl, other.impl);
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}
// Clear out a target, if there is one
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)
functor = manager(functor, destroy_functor);
manager = 0;
invoker = 0;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}
protected:
void assign_to_own(const BOOST_FUNCTION_BASE& f)
{
if (this == &f)
return;
this->clear();
if (!f.empty()) {
# ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
impl_type* other_impl = reinterpret_cast<impl_type*>(f.impl);
this->impl = static_cast<void*>(other_impl->clone());
# else
this->invoker = f.invoker;
this->manager = f.manager;
this->functor = f.manager(f.functor, clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}
}
template<typename Functor>
void assign_to(const Functor& f)
{
typedef typename IF<(is_pointer<Functor>::value),
function_ptr_tag,
function_obj_tag>::type tag;
this->assign_to(f, tag());
}
template<typename FunctionPtr>
void assign_to(FunctionPtr f, function_ptr_tag)
{
clear();
if (f) {
typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
FunctionPtr,
Allocator,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>::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;
manager = &functor_manager<FunctionPtr, Allocator>::manage;
functor = manager(any_pointer(reinterpret_cast<void (*)()>(f)),
clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}
}
template<typename FunctionObj>
void assign_to(const FunctionObj& f, function_obj_tag)
{
clear();
if (!has_empty_target(&f)) {
typedef
typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
FunctionObj,
Allocator,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>::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;
manager = &functor_manager<FunctionObj, Allocator>::manage;
functor = manager(any_pointer(const_cast<FunctionObj*>(&f)),
clone_functor);
# endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
}
}
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typedef result_type (*invoker_type)(any_pointer,
bool BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS);
invoker_type invoker;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
};
} // end namespace function
} // end namespace detail
template<
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS,
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
class BOOST_FUNCTION_FUNCTION :
public detail::function::BOOST_FUNCTION_BASE<R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS,
Policy, Mixin, Allocator>
{
typedef detail::function::BOOST_FUNCTION_BASE<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS,
Policy, Mixin, Allocator> base_type;
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
typedef typename base_type::impl_type impl_type;
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
public:
typedef typename base_type::result_type result_type;
typedef typename base_type::policy_type policy_type;
typedef typename base_type::mixin_type mixin_type;
typedef typename base_type::allocator_type allocator_type;
BOOST_FUNCTION_FUNCTION() : base_type() {}
template<typename Functor>
BOOST_FUNCTION_FUNCTION(const Functor& f) : base_type()
{
this->assign_to(f);
}
#ifdef __BORLANDC__
template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor* f) : base_type()
{
this->assign_to(f);
}
#endif // __BORLANDC__
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : base_type()
{
this->assign_to_own(f);
}
// Invoke the target
result_type operator()(BOOST_FUNCTION_PARMS)
{
assert(!this->empty());
policy_type policy;
policy.precall(this);
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
impl_type* i = reinterpret_cast<impl_type*>(this->impl);
result_type result = i->call(BOOST_FUNCTION_ARGS);
#else
result_type result = this->invoker(functor,
false BOOST_FUNCTION_COMMA
BOOST_FUNCTION_ARGS);
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
policy.postcall(this);
return result;
}
result_type operator()(BOOST_FUNCTION_PARMS) const
{
assert(!this->empty());
policy_type policy;
policy.precall(this);
#ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
const impl_type* i = reinterpret_cast<const impl_type*>(this->impl);
result_type result = i->call(BOOST_FUNCTION_ARGS);
#else
result_type result = this->invoker(functor,
true BOOST_FUNCTION_COMMA
BOOST_FUNCTION_ARGS);
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
policy.postcall(this);
return result;
}
template<typename Functor>
BOOST_FUNCTION_FUNCTION& operator=(const Functor& f)
{
this->assign_to(f);
return *this;
}
#ifdef __BORLANDC__
template<typename Functor>
BOOST_FUNCTION_FUNCTION& operator=(Functor* f)
{
this->assign_to(f);
return *this;
}
#endif // __BORLANDC__
template<typename Functor>
void set(const Functor& f)
{
this->assign_to(f);
}
#ifdef __BORLANDC__
template<typename Functor>
void set(Functor* f)
{
this->assign_to(f);
}
#endif // __BORLANDC__
// Assignment from another BOOST_FUNCTION_FUNCTION
BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
{
this->assign_to_own(f);
return *this;
}
// Assignment from another BOOST_FUNCTION_FUNCTION
void set(const BOOST_FUNCTION_FUNCTION& f)
{
this->assign_to_own(f);
}
};
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Policy, typename Mixin, typename Allocator>
inline void swap(BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS ,
Policy,
Mixin,
Allocator
>& f1,
BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS,
Policy,
Mixin,
Allocator
>& f2)
{
f1.swap(f2);
}
}
// Cleanup after ourselves...
#undef BOOST_FUNCTION_INIT