mirror of
https://github.com/boostorg/function.git
synced 2025-07-23 17:37:14 +02:00
function_base.hpp:
- Add trivial_manager that does nothing but copy object pointers - Add is_ref to determine if a type is a reference_wrapper - Add function_obj_ref_tag for reference_wrappers - Teach get_function_tag about reference_wrappers function_template.hpp: - Add assign_to overload for reference_wrappers (these don't throw) [SVN r11875]
This commit is contained in:
@ -23,6 +23,7 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/type_traits.hpp>
|
#include <boost/type_traits.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -70,6 +71,37 @@ namespace boost {
|
|||||||
typedef typename select::template Result<Then,Else>::type type;
|
typedef typename select::template Result<Then,Else>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Determine if the incoming argument is a reference_wrapper
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template<typename T>
|
||||||
|
struct is_ref
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_ref<reference_wrapper<T> >
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||||
|
};
|
||||||
|
#else // no partial specialization
|
||||||
|
typedef char yes_type;
|
||||||
|
typedef double no_type;
|
||||||
|
|
||||||
|
no_type is_ref_tester(...);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
yes_type is_ref_tester(reference_wrapper<T>*);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_ref
|
||||||
|
{
|
||||||
|
static T* t;
|
||||||
|
BOOST_STATIC_CONSTANT(bool,
|
||||||
|
value = (sizeof(is_ref_tester(t)) == sizeof(yes_type)));
|
||||||
|
};
|
||||||
|
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A union of a function pointer and a void pointer. This is necessary
|
* A union of a function pointer and a void pointer. This is necessary
|
||||||
* because 5.2.10/6 allows reinterpret_cast<> to safely cast between
|
* because 5.2.10/6 allows reinterpret_cast<> to safely cast between
|
||||||
@ -122,6 +154,7 @@ namespace boost {
|
|||||||
struct function_ptr_tag {};
|
struct function_ptr_tag {};
|
||||||
struct function_obj_tag {};
|
struct function_obj_tag {};
|
||||||
struct member_ptr_tag {};
|
struct member_ptr_tag {};
|
||||||
|
struct function_obj_ref_tag {};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
class get_function_tag
|
class get_function_tag
|
||||||
@ -130,12 +163,26 @@ namespace boost {
|
|||||||
function_ptr_tag,
|
function_ptr_tag,
|
||||||
function_obj_tag>::type ptr_or_obj_tag;
|
function_obj_tag>::type ptr_or_obj_tag;
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename IF<(is_member_pointer<F>::value),
|
typedef typename IF<(is_member_pointer<F>::value),
|
||||||
member_ptr_tag,
|
member_ptr_tag,
|
||||||
ptr_or_obj_tag>::type type;
|
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
||||||
|
public:
|
||||||
|
typedef typename IF<(is_ref<F>::value),
|
||||||
|
function_obj_ref_tag,
|
||||||
|
ptr_or_obj_or_mem_tag>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The trivial manager does nothing but return the same pointer (if we
|
||||||
|
// are cloning) or return the null pointer (if we are deleting).
|
||||||
|
any_pointer trivial_manager(any_pointer f,
|
||||||
|
functor_manager_operation_type op)
|
||||||
|
{
|
||||||
|
if (op == clone_functor_tag)
|
||||||
|
return f;
|
||||||
|
else
|
||||||
|
return any_pointer(reinterpret_cast<void*>(0));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -391,6 +391,28 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename FunctionObj>
|
||||||
|
void assign_to(const reference_wrapper<FunctionObj>& f,
|
||||||
|
detail::function::function_obj_ref_tag)
|
||||||
|
{
|
||||||
|
if (!detail::function::has_empty_target(&f.get())) {
|
||||||
|
typedef
|
||||||
|
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||||
|
FunctionObj,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>::type
|
||||||
|
invoker_type;
|
||||||
|
|
||||||
|
invoker = &invoker_type::invoke;
|
||||||
|
manager = &detail::function::trivial_manager;
|
||||||
|
functor =
|
||||||
|
manager(detail::function::any_pointer(
|
||||||
|
const_cast<FunctionObj*>(&f.get())),
|
||||||
|
detail::function::clone_functor_tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user