mirror of
https://github.com/boostorg/function.git
synced 2025-07-25 02:17:14 +02:00
function_base.hpp:
- has_empty_target modified to deal only with function objects, and to not require pointers to the function objects. function_template.hpp: - Don't use '&' operation on incoming function objects [SVN r13318]
This commit is contained in:
@ -34,6 +34,8 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace function {
|
namespace function {
|
||||||
|
template<bool> struct truth {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The IF implementation is temporary code. When a Boost metaprogramming
|
* The IF implementation is temporary code. When a Boost metaprogramming
|
||||||
* library is introduced, Boost.Function will use it instead.
|
* library is introduced, Boost.Function will use it instead.
|
||||||
@ -156,7 +158,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;
|
||||||
@ -176,7 +178,8 @@ namespace boost {
|
|||||||
|
|
||||||
// For function pointers, the manager is trivial
|
// For function pointers, the manager is trivial
|
||||||
static inline any_pointer
|
static inline any_pointer
|
||||||
manager(any_pointer function_ptr, functor_manager_operation_type op,
|
manager(any_pointer function_ptr,
|
||||||
|
functor_manager_operation_type op,
|
||||||
function_ptr_tag)
|
function_ptr_tag)
|
||||||
{
|
{
|
||||||
if (op == clone_functor_tag)
|
if (op == clone_functor_tag)
|
||||||
@ -333,92 +336,20 @@ namespace boost {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace function {
|
namespace function {
|
||||||
/**
|
// The result is not a Boost.Function object, so we assume that this
|
||||||
* Determine if the given target is empty.
|
// target is not empty
|
||||||
*/
|
template<typename FunctionObj>
|
||||||
|
inline bool has_empty_target(const FunctionObj&, truth<false>)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback - assume target is not empty
|
// The result is a Boost.Function object, so query whether it is empty
|
||||||
inline bool has_empty_target(...)
|
// or not
|
||||||
|
template<typename FunctionObj>
|
||||||
|
inline bool has_empty_target(const FunctionObj& f, truth<true>)
|
||||||
{
|
{
|
||||||
return false;
|
return f.empty();
|
||||||
}
|
|
||||||
|
|
||||||
// If the target is a 'function', query the empty() method
|
|
||||||
inline bool has_empty_target(const function_base* af)
|
|
||||||
{
|
|
||||||
return af->empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the target is a 'function', query the empty() method
|
|
||||||
inline bool has_empty_target(const function_base& af)
|
|
||||||
{
|
|
||||||
return af.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function pointer is empty if it is null
|
|
||||||
template<typename R>
|
|
||||||
inline bool has_empty_target(R (*f)())
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1>
|
|
||||||
inline bool has_empty_target(R (*f)(T1))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7, typename T8>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7, typename T8, typename T9>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
}
|
||||||
} // end namespace function
|
} // end namespace function
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
@ -430,14 +361,18 @@ namespace boost {
|
|||||||
inline void postcall(const function_base*) {}
|
inline void postcall(const function_base*) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The default function mixin does nothing. The assignment and copy-construction operators
|
// The default function mixin does nothing. The assignment and
|
||||||
// are all defined because MSVC defines broken versions.
|
// copy-construction operators are all defined because MSVC defines broken
|
||||||
struct empty_function_mixin {
|
// versions.
|
||||||
empty_function_mixin() {};
|
struct empty_function_mixin
|
||||||
empty_function_mixin(const empty_function_mixin&) {};
|
{
|
||||||
|
empty_function_mixin() {}
|
||||||
|
empty_function_mixin(const empty_function_mixin&) {}
|
||||||
|
|
||||||
empty_function_mixin& operator=(const empty_function_mixin&)
|
empty_function_mixin& operator=(const empty_function_mixin&)
|
||||||
{return *this; }
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,9 +361,12 @@ namespace boost {
|
|||||||
// Clear out a target, if there is one
|
// Clear out a target, if there is one
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -374,7 +377,8 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,9 +403,10 @@ namespace boost {
|
|||||||
invoker_type;
|
invoker_type;
|
||||||
|
|
||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
function_base::manager = &detail::function::functor_manager<FunctionPtr,
|
function_base::manager =
|
||||||
Allocator>::manage;
|
&detail::function::functor_manager<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)
|
||||||
@ -421,7 +426,11 @@ namespace boost {
|
|||||||
template<typename FunctionObj>
|
template<typename FunctionObj>
|
||||||
void assign_to(FunctionObj f, detail::function::function_obj_tag)
|
void assign_to(FunctionObj f, detail::function::function_obj_tag)
|
||||||
{
|
{
|
||||||
if (!detail::function::has_empty_target(&f)) {
|
typedef detail::function::truth<
|
||||||
|
boost::is_base_and_derived<function_base, FunctionObj>::value>
|
||||||
|
is_boost_function;
|
||||||
|
|
||||||
|
if (!detail::function::has_empty_target(f, is_boost_function())) {
|
||||||
typedef
|
typedef
|
||||||
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||||
FunctionObj,
|
FunctionObj,
|
||||||
@ -431,11 +440,23 @@ namespace boost {
|
|||||||
invoker_type;
|
invoker_type;
|
||||||
|
|
||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
function_base::manager = &detail::function::functor_manager<FunctionObj,
|
function_base::manager = &detail::function::functor_manager<
|
||||||
Allocator>::manage;
|
FunctionObj, Allocator>::manage;
|
||||||
|
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||||
|
typedef typename Allocator::template rebind<FunctionObj>::other
|
||||||
|
allocator_type;
|
||||||
|
typedef typename allocator_type::pointer pointer_type;
|
||||||
|
allocator_type allocator;
|
||||||
|
pointer_type copy = allocator.allocate(1);
|
||||||
|
allocator.construct(copy, f);
|
||||||
|
|
||||||
|
// Get back to the original pointer type
|
||||||
|
FunctionObj* new_f = static_cast<FunctionObj*>(copy);
|
||||||
|
#else
|
||||||
|
FunctionObj* new_f = new FunctionObj(f);
|
||||||
|
#endif // BOOST_NO_STD_ALLOCATOR
|
||||||
function_base::functor =
|
function_base::functor =
|
||||||
function_base::manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)),
|
detail::function::any_pointer(static_cast<void*>(new_f));
|
||||||
detail::function::clone_functor_tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +464,11 @@ namespace boost {
|
|||||||
void assign_to(const reference_wrapper<FunctionObj>& f,
|
void assign_to(const reference_wrapper<FunctionObj>& f,
|
||||||
detail::function::function_obj_ref_tag)
|
detail::function::function_obj_ref_tag)
|
||||||
{
|
{
|
||||||
if (!detail::function::has_empty_target(&f.get())) {
|
typedef detail::function::truth<
|
||||||
|
boost::is_base_and_derived<function_base, FunctionObj>::value>
|
||||||
|
is_boost_function;
|
||||||
|
|
||||||
|
if (!detail::function::has_empty_target(f.get(), is_boost_function())) {
|
||||||
typedef
|
typedef
|
||||||
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||||
FunctionObj,
|
FunctionObj,
|
||||||
@ -455,9 +480,10 @@ namespace boost {
|
|||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
function_base::manager = &detail::function::trivial_manager;
|
function_base::manager = &detail::function::trivial_manager;
|
||||||
function_base::functor =
|
function_base::functor =
|
||||||
function_base::manager(detail::function::any_pointer(
|
function_base::manager(
|
||||||
const_cast<FunctionObj*>(&f.get())),
|
detail::function::any_pointer(
|
||||||
detail::function::clone_functor_tag);
|
const_cast<FunctionObj*>(f.get_pointer())),
|
||||||
|
detail::function::clone_functor_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,4 +547,3 @@ namespace boost {
|
|||||||
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user