mirror of
https://github.com/boostorg/function.git
synced 2025-07-23 17:37:14 +02:00
function_base.hpp:
function_template.hpp: - Add support for storing member function pointers directly within the Boost.Function object, without allocating any extra memory [SVN r12568]
This commit is contained in:
@ -86,13 +86,17 @@ namespace boost {
|
|||||||
* so function requires a union of the two. */
|
* so function requires a union of the two. */
|
||||||
union any_pointer
|
union any_pointer
|
||||||
{
|
{
|
||||||
|
class incomplete;
|
||||||
|
|
||||||
void* obj_ptr;
|
void* obj_ptr;
|
||||||
const void* const_obj_ptr;
|
const void* const_obj_ptr;
|
||||||
void (*func_ptr)();
|
void (*func_ptr)();
|
||||||
|
void (incomplete::*mem_func_ptr)();
|
||||||
|
|
||||||
explicit any_pointer(void* p) : obj_ptr(p) {}
|
explicit any_pointer(void* p) : obj_ptr(p) {}
|
||||||
explicit any_pointer(const void* p) : const_obj_ptr(p) {}
|
explicit any_pointer(const void* p) : const_obj_ptr(p) {}
|
||||||
explicit any_pointer(void (*p)()) : func_ptr(p) {}
|
explicit any_pointer(void (*p)()) : func_ptr(p) {}
|
||||||
|
explicit any_pointer(void (incomplete::*p)()) : mem_func_ptr(p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +143,7 @@ namespace boost {
|
|||||||
function_ptr_tag,
|
function_ptr_tag,
|
||||||
function_obj_tag>::type ptr_or_obj_tag;
|
function_obj_tag>::type ptr_or_obj_tag;
|
||||||
|
|
||||||
typedef typename IF<(is_member_pointer<F>::value),
|
typedef typename IF<(is_member_function_pointer<F>::value),
|
||||||
member_ptr_tag,
|
member_ptr_tag,
|
||||||
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
||||||
|
|
||||||
@ -156,7 +160,7 @@ namespace boost {
|
|||||||
// The trivial manager does nothing but return the same pointer (if we
|
// The trivial manager does nothing but return the same pointer (if we
|
||||||
// are cloning) or return the null pointer (if we are deleting).
|
// are cloning) or return the null pointer (if we are deleting).
|
||||||
inline any_pointer trivial_manager(any_pointer f,
|
inline any_pointer trivial_manager(any_pointer f,
|
||||||
functor_manager_operation_type op)
|
functor_manager_operation_type op)
|
||||||
{
|
{
|
||||||
if (op == clone_functor_tag)
|
if (op == clone_functor_tag)
|
||||||
return f;
|
return f;
|
||||||
|
@ -45,7 +45,11 @@
|
|||||||
#define BOOST_FUNCTION_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_FUNCTION_INVOKER \
|
||||||
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
|
||||||
BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_MEM_FUNCTION_INVOKER \
|
||||||
|
BOOST_JOIN(member_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_MEM_VOID_FUNCTION_INVOKER \
|
||||||
|
BOOST_JOIN(member_void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
|
||||||
BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
|
||||||
@ -56,6 +60,8 @@
|
|||||||
BOOST_JOIN(stateless_void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(stateless_void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
|
||||||
BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER \
|
||||||
|
BOOST_JOIN(get_member_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
|
||||||
BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER \
|
||||||
@ -88,7 +94,6 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
{
|
{
|
||||||
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
|
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
|
||||||
f(BOOST_FUNCTION_ARGS);
|
f(BOOST_FUNCTION_ARGS);
|
||||||
@ -96,6 +101,39 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if BOOST_FUNCTION_NUM_ARGS > 0
|
||||||
|
template<
|
||||||
|
typename MemberPtr,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_MEM_FUNCTION_INVOKER
|
||||||
|
{
|
||||||
|
static R invoke(any_pointer member_ptr BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_PARMS)
|
||||||
|
{
|
||||||
|
MemberPtr f = (MemberPtr)(member_ptr.mem_func_ptr);
|
||||||
|
return mem_fn(f)(BOOST_FUNCTION_ARGS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename MemberPtr,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_MEM_VOID_FUNCTION_INVOKER
|
||||||
|
{
|
||||||
|
static unusable invoke(any_pointer member_ptr BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_PARMS)
|
||||||
|
{
|
||||||
|
MemberPtr f = (MemberPtr)(member_ptr.mem_func_ptr);
|
||||||
|
mem_fn(f)(BOOST_FUNCTION_ARGS);
|
||||||
|
return unusable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename FunctionObj,
|
typename FunctionObj,
|
||||||
typename R BOOST_FUNCTION_COMMA
|
typename R BOOST_FUNCTION_COMMA
|
||||||
@ -182,6 +220,29 @@ namespace boost {
|
|||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if BOOST_FUNCTION_NUM_ARGS > 0
|
||||||
|
template<
|
||||||
|
typename MemberPtr,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
||||||
|
{
|
||||||
|
typedef typename IF<(is_void<R>::value),
|
||||||
|
BOOST_FUNCTION_MEM_VOID_FUNCTION_INVOKER<
|
||||||
|
MemberPtr,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>,
|
||||||
|
BOOST_FUNCTION_MEM_FUNCTION_INVOKER<
|
||||||
|
MemberPtr,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename FunctionObj,
|
typename FunctionObj,
|
||||||
typename R BOOST_FUNCTION_COMMA
|
typename R BOOST_FUNCTION_COMMA
|
||||||
@ -350,7 +411,9 @@ namespace boost {
|
|||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (function_base::manager)
|
if (function_base::manager)
|
||||||
function_base::functor = function_base::manager(function_base::functor, detail::function::destroy_functor_tag);
|
function_base::functor = function_base::manager(
|
||||||
|
function_base::functor,
|
||||||
|
detail::function::destroy_functor_tag);
|
||||||
|
|
||||||
function_base::manager = 0;
|
function_base::manager = 0;
|
||||||
invoker = 0;
|
invoker = 0;
|
||||||
@ -362,7 +425,9 @@ namespace boost {
|
|||||||
if (!f.empty()) {
|
if (!f.empty()) {
|
||||||
invoker = f.invoker;
|
invoker = f.invoker;
|
||||||
function_base::manager = f.manager;
|
function_base::manager = f.manager;
|
||||||
function_base::functor = f.manager(f.functor, detail::function::clone_functor_tag);
|
function_base::functor = f.manager(
|
||||||
|
f.functor,
|
||||||
|
detail::function::clone_functor_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,22 +444,24 @@ namespace boost {
|
|||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
typedef typename detail::function::BOOST_FUNCTION_GET_FUNCTION_INVOKER<
|
typedef typename detail::function::
|
||||||
FunctionPtr,
|
BOOST_FUNCTION_GET_FUNCTION_INVOKER<
|
||||||
R BOOST_FUNCTION_COMMA
|
FunctionPtr,
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS
|
R BOOST_FUNCTION_COMMA
|
||||||
>::type
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>::type
|
||||||
invoker_type;
|
invoker_type;
|
||||||
|
|
||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
function_base::manager = &detail::function::functor_manager<FunctionPtr,
|
function_base::manager = &detail::function::functor_manager<
|
||||||
Allocator>::manage;
|
FunctionPtr, Allocator>::manage;
|
||||||
function_base::functor = function_base::manager(detail::function::any_pointer(
|
function_base::functor =
|
||||||
|
function_base::manager(
|
||||||
|
detail::function::any_pointer(
|
||||||
// should be a reinterpret cast, but some compilers
|
// should be a reinterpret cast, but some compilers
|
||||||
// insist on giving cv-qualifiers to free functions
|
// insist on giving cv-qualifiers to free functions
|
||||||
(void (*)())(f)
|
(void (*)())(f)),
|
||||||
),
|
detail::function::clone_functor_tag);
|
||||||
detail::function::clone_functor_tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +469,24 @@ namespace boost {
|
|||||||
template<typename MemberPtr>
|
template<typename MemberPtr>
|
||||||
void assign_to(MemberPtr f, detail::function::member_ptr_tag)
|
void assign_to(MemberPtr f, detail::function::member_ptr_tag)
|
||||||
{
|
{
|
||||||
this->assign_to(mem_fn(f));
|
clear();
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
typedef detail::function::any_pointer any_pointer;
|
||||||
|
|
||||||
|
typedef typename detail::function::
|
||||||
|
BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER<
|
||||||
|
MemberPtr,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>::type
|
||||||
|
invoker_type;
|
||||||
|
|
||||||
|
invoker = &invoker_type::invoke;
|
||||||
|
function_base::manager = &detail::function::trivial_manager;
|
||||||
|
function_base::functor =
|
||||||
|
any_pointer((void (any_pointer::incomplete::*)())(f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // BOOST_FUNCTION_NUM_ARGS > 0
|
#endif // BOOST_FUNCTION_NUM_ARGS > 0
|
||||||
|
|
||||||
@ -501,6 +585,8 @@ namespace boost {
|
|||||||
#undef BOOST_FUNCTION_INVOKER_BASE
|
#undef BOOST_FUNCTION_INVOKER_BASE
|
||||||
#undef BOOST_FUNCTION_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_FUNCTION_INVOKER
|
||||||
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
|
||||||
|
#undef BOOST_FUNCTION_MEM_FUNCTION_INVOKER
|
||||||
|
#undef BOOST_FUNCTION_MEM_VOID_FUNCTION_INVOKER
|
||||||
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
|
Reference in New Issue
Block a user