mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-14 09:32:20 +00:00
2349a51b12
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9274 a592a061-630c-0410-9148-cb99ea01b6c8
661 lines
20 KiB
C++
661 lines
20 KiB
C++
// Boost.Function library
|
|
|
|
// Copyright Douglas Gregor 2001-2004. Use, modification and
|
|
// distribution is subject to the Boost Software License, Version
|
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// For more information, see http://www.boost.org
|
|
|
|
#ifndef BOOST_FUNCTION_BASE_HEADER
|
|
#define BOOST_FUNCTION_BASE_HEADER
|
|
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <new>
|
|
#include <typeinfo>
|
|
#include <boost/config.hpp>
|
|
#include <boost/assert.hpp>
|
|
#include <boost/type_traits/is_integral.hpp>
|
|
#include <boost/type_traits/composite_traits.hpp>
|
|
#include <boost/type_traits/is_stateless.hpp>
|
|
#include <boost/ref.hpp>
|
|
#include <boost/pending/ct_if.hpp>
|
|
#include <boost/detail/workaround.hpp>
|
|
#ifndef BOOST_NO_SFINAE
|
|
# include "boost/utility/enable_if.hpp"
|
|
#else
|
|
# include "boost/mpl/bool.hpp"
|
|
#endif
|
|
#include <boost/function_equal.hpp>
|
|
|
|
// Borrowed from Boost.Python library: determines the cases where we
|
|
// need to use std::type_info::name to compare instead of operator==.
|
|
# if (defined(__GNUC__) && __GNUC__ >= 3) \
|
|
|| defined(_AIX) \
|
|
|| ( defined(__sgi) && defined(__host_mips))
|
|
# include <cstring>
|
|
# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \
|
|
(std::strcmp((X).name(),(Y).name()) == 0)
|
|
# else
|
|
# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
|
|
#endif
|
|
|
|
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
|
|
# define BOOST_FUNCTION_TARGET_FIX(x) x
|
|
#else
|
|
# define BOOST_FUNCTION_TARGET_FIX(x)
|
|
#endif // not MSVC
|
|
|
|
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
|
|
// Work around a compiler bug.
|
|
// boost::python::objects::function has to be seen by the compiler before the
|
|
// boost::function class template.
|
|
namespace boost { namespace python { namespace objects {
|
|
class function;
|
|
}}}
|
|
#endif
|
|
|
|
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
|
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|
|
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
|
|
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
|
|
#endif
|
|
|
|
#define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \
|
|
typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \
|
|
(::boost::is_integral<Functor>::value)>::value), \
|
|
Type>::type
|
|
|
|
|
|
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
|
|
namespace boost {
|
|
|
|
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
|
|
// The library shipping with MIPSpro 7.3.1.3m has a broken allocator<void>
|
|
class function_base;
|
|
|
|
template<typename Signature,
|
|
typename Allocator = std::allocator<function_base> >
|
|
class function;
|
|
#else
|
|
template<typename Signature, typename Allocator = std::allocator<void> >
|
|
class function;
|
|
#endif
|
|
|
|
template<typename Signature, typename Allocator>
|
|
inline void swap(function<Signature, Allocator>& f1,
|
|
function<Signature, Allocator>& f2)
|
|
{
|
|
f1.swap(f2);
|
|
}
|
|
|
|
} // end namespace boost
|
|
#endif // have partial specialization
|
|
|
|
namespace boost {
|
|
namespace detail {
|
|
namespace function {
|
|
/**
|
|
* 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
|
|
* function pointer types and 5.2.9/10 allows static_cast<> to safely
|
|
* cast between a void pointer and an object pointer. But it is not legal
|
|
* to cast between a function pointer and a void* (in either direction),
|
|
* so function requires a union of the two. */
|
|
union any_pointer
|
|
{
|
|
void* obj_ptr;
|
|
const void* const_obj_ptr;
|
|
void (*func_ptr)();
|
|
char data[1];
|
|
};
|
|
|
|
inline any_pointer make_any_pointer(void* o)
|
|
{
|
|
any_pointer p;
|
|
p.obj_ptr = o;
|
|
return p;
|
|
}
|
|
|
|
inline any_pointer make_any_pointer(const void* o)
|
|
{
|
|
any_pointer p;
|
|
p.const_obj_ptr = o;
|
|
return p;
|
|
}
|
|
|
|
inline any_pointer make_any_pointer(void (*f)())
|
|
{
|
|
any_pointer p;
|
|
p.func_ptr = f;
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
* The unusable class is a placeholder for unused function arguments
|
|
* It is also completely unusable except that it constructable from
|
|
* anything. This helps compilers without partial specialization to
|
|
* handle Boost.Function objects returning void.
|
|
*/
|
|
struct unusable
|
|
{
|
|
unusable() {}
|
|
template<typename T> unusable(const T&) {}
|
|
};
|
|
|
|
/* Determine the return type. This supports compilers that do not support
|
|
* void returns or partial specialization by silently changing the return
|
|
* type to "unusable".
|
|
*/
|
|
template<typename T> struct function_return_type { typedef T type; };
|
|
|
|
template<>
|
|
struct function_return_type<void>
|
|
{
|
|
typedef unusable type;
|
|
};
|
|
|
|
// The operation type to perform on the given functor/function pointer
|
|
enum functor_manager_operation_type {
|
|
clone_functor_tag,
|
|
destroy_functor_tag,
|
|
check_functor_type_tag
|
|
};
|
|
|
|
// Tags used to decide between different types of functions
|
|
struct function_ptr_tag {};
|
|
struct function_obj_tag {};
|
|
struct member_ptr_tag {};
|
|
struct function_obj_ref_tag {};
|
|
struct stateless_function_obj_tag {};
|
|
|
|
template<typename F>
|
|
class get_function_tag
|
|
{
|
|
typedef typename ct_if<(is_pointer<F>::value),
|
|
function_ptr_tag,
|
|
function_obj_tag>::type ptr_or_obj_tag;
|
|
|
|
typedef typename ct_if<(is_member_pointer<F>::value),
|
|
member_ptr_tag,
|
|
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
|
|
|
typedef typename ct_if<(is_reference_wrapper<F>::value),
|
|
function_obj_ref_tag,
|
|
ptr_or_obj_or_mem_tag>::type or_ref_tag;
|
|
|
|
public:
|
|
typedef typename ct_if<(is_stateless<F>::value),
|
|
stateless_function_obj_tag,
|
|
or_ref_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).
|
|
template<typename F>
|
|
struct trivial_manager
|
|
{
|
|
static inline any_pointer
|
|
get(any_pointer f, functor_manager_operation_type op)
|
|
{
|
|
switch (op) {
|
|
case clone_functor_tag: return f;
|
|
|
|
case destroy_functor_tag:
|
|
return make_any_pointer(reinterpret_cast<void*>(0));
|
|
|
|
case check_functor_type_tag:
|
|
{
|
|
std::type_info* t = static_cast<std::type_info*>(f.obj_ptr);
|
|
return BOOST_FUNCTION_COMPARE_TYPE_ID(typeid(F), *t)?
|
|
f
|
|
: make_any_pointer(reinterpret_cast<void*>(0));
|
|
}
|
|
}
|
|
|
|
// Clears up a warning with GCC 3.2.3
|
|
return make_any_pointer(reinterpret_cast<void*>(0));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* The functor_manager class contains a static function "manage" which
|
|
* can clone or destroy the given function/function object pointer.
|
|
*/
|
|
template<typename Functor, typename Allocator>
|
|
struct functor_manager
|
|
{
|
|
private:
|
|
typedef Functor functor_type;
|
|
|
|
// For function pointers, the manager is trivial
|
|
static inline any_pointer
|
|
manager(any_pointer function_ptr,
|
|
functor_manager_operation_type op,
|
|
function_ptr_tag)
|
|
{
|
|
if (op == clone_functor_tag)
|
|
return function_ptr;
|
|
else
|
|
return make_any_pointer(static_cast<void (*)()>(0));
|
|
}
|
|
|
|
// For function object pointers, we clone the pointer to each
|
|
// function has its own version.
|
|
static inline any_pointer
|
|
manager(any_pointer function_obj_ptr,
|
|
functor_manager_operation_type op,
|
|
function_obj_tag)
|
|
{
|
|
#ifndef BOOST_NO_STD_ALLOCATOR
|
|
typedef typename Allocator::template rebind<functor_type>::other
|
|
allocator_type;
|
|
typedef typename allocator_type::pointer pointer_type;
|
|
#else
|
|
typedef functor_type* pointer_type;
|
|
#endif // BOOST_NO_STD_ALLOCATOR
|
|
|
|
# ifndef BOOST_NO_STD_ALLOCATOR
|
|
allocator_type allocator;
|
|
# endif // BOOST_NO_STD_ALLOCATOR
|
|
|
|
if (op == clone_functor_tag) {
|
|
functor_type* f =
|
|
static_cast<functor_type*>(function_obj_ptr.obj_ptr);
|
|
|
|
// Clone the functor
|
|
# ifndef BOOST_NO_STD_ALLOCATOR
|
|
pointer_type copy = allocator.allocate(1);
|
|
allocator.construct(copy, *f);
|
|
|
|
// Get back to the original pointer type
|
|
functor_type* new_f = static_cast<functor_type*>(copy);
|
|
# else
|
|
functor_type* new_f = new functor_type(*f);
|
|
# endif // BOOST_NO_STD_ALLOCATOR
|
|
return make_any_pointer(static_cast<void*>(new_f));
|
|
}
|
|
else {
|
|
/* Cast from the void pointer to the functor pointer type */
|
|
functor_type* f =
|
|
reinterpret_cast<functor_type*>(function_obj_ptr.obj_ptr);
|
|
|
|
# ifndef BOOST_NO_STD_ALLOCATOR
|
|
/* Cast from the functor pointer type to the allocator's pointer
|
|
type */
|
|
pointer_type victim = static_cast<pointer_type>(f);
|
|
|
|
// Destroy and deallocate the functor
|
|
allocator.destroy(victim);
|
|
allocator.deallocate(victim, 1);
|
|
# else
|
|
delete f;
|
|
# endif // BOOST_NO_STD_ALLOCATOR
|
|
|
|
return make_any_pointer(static_cast<void*>(0));
|
|
}
|
|
}
|
|
public:
|
|
/* Dispatch to an appropriate manager based on whether we have a
|
|
function pointer or a function object pointer. */
|
|
static any_pointer
|
|
manage(any_pointer functor_ptr, functor_manager_operation_type op)
|
|
{
|
|
if (op == check_functor_type_tag) {
|
|
std::type_info* type =
|
|
static_cast<std::type_info*>(functor_ptr.obj_ptr);
|
|
return (BOOST_FUNCTION_COMPARE_TYPE_ID(typeid(Functor), *type)?
|
|
functor_ptr
|
|
: make_any_pointer(reinterpret_cast<void*>(0)));
|
|
}
|
|
else {
|
|
typedef typename get_function_tag<functor_type>::type tag_type;
|
|
return manager(functor_ptr, op, tag_type());
|
|
}
|
|
}
|
|
};
|
|
|
|
// A type that is only used for comparisons against zero
|
|
struct useless_clear_type {};
|
|
|
|
#ifdef BOOST_NO_SFINAE
|
|
// These routines perform comparisons between a Boost.Function
|
|
// object and an arbitrary function object (when the last
|
|
// parameter is mpl::bool_<false>) or against zero (when the
|
|
// last parameter is mpl::bool_<true>). They are only necessary
|
|
// for compilers that don't support SFINAE.
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_equal(const Function& f, const Functor&, int, mpl::bool_<true>)
|
|
{ return f.empty(); }
|
|
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_not_equal(const Function& f, const Functor&, int,
|
|
mpl::bool_<true>)
|
|
{ return !f.empty(); }
|
|
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_equal(const Function& f, const Functor& g, long,
|
|
mpl::bool_<false>)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return function_equal(*fp, g);
|
|
else return false;
|
|
}
|
|
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_equal(const Function& f, const reference_wrapper<Functor>& g,
|
|
int, mpl::bool_<false>)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return fp == g.get_pointer();
|
|
else return false;
|
|
}
|
|
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_not_equal(const Function& f, const Functor& g, long,
|
|
mpl::bool_<false>)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return !function_equal(*fp, g);
|
|
else return true;
|
|
}
|
|
|
|
template<typename Function, typename Functor>
|
|
bool
|
|
compare_not_equal(const Function& f,
|
|
const reference_wrapper<Functor>& g, int,
|
|
mpl::bool_<false>)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return fp != g.get_pointer();
|
|
else return true;
|
|
}
|
|
#endif // BOOST_NO_SFINAE
|
|
} // end namespace function
|
|
} // end namespace detail
|
|
|
|
/**
|
|
* The function_base class contains the basic elements needed for the
|
|
* function1, function2, function3, etc. classes. It is common to all
|
|
* functions (and as such can be used to tell if we have one of the
|
|
* functionN objects).
|
|
*/
|
|
class function_base
|
|
{
|
|
public:
|
|
function_base() : manager(0)
|
|
{
|
|
functor.obj_ptr = 0;
|
|
}
|
|
|
|
// Is this function empty?
|
|
bool empty() const { return !manager; }
|
|
|
|
template<typename Functor>
|
|
Functor* target()
|
|
{
|
|
if (!manager) return 0;
|
|
|
|
detail::function::any_pointer result =
|
|
manager(detail::function::make_any_pointer(&typeid(Functor)),
|
|
detail::function::check_functor_type_tag);
|
|
if (!result.obj_ptr) return 0;
|
|
else {
|
|
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
|
return get_functor_pointer<Functor>(tag(), 0);
|
|
}
|
|
}
|
|
|
|
template<typename Functor>
|
|
const Functor* target() const
|
|
{
|
|
if (!manager) return 0;
|
|
|
|
detail::function::any_pointer result =
|
|
manager(detail::function::make_any_pointer(&typeid(Functor)),
|
|
detail::function::check_functor_type_tag);
|
|
if (!result.obj_ptr) return 0;
|
|
else {
|
|
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
|
return get_functor_pointer<Functor>(tag(), 0);
|
|
}
|
|
}
|
|
|
|
template<typename F>
|
|
bool contains(const F& f) const
|
|
{
|
|
if (const F* fp = this->template target<F>()) {
|
|
return function_equal(*fp, f);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3
|
|
// GCC 3.3 and newer cannot copy with the global operator==, due to
|
|
// problems with instantiation of function return types before it
|
|
// has been verified that the argument types match up.
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator==(Functor g) const
|
|
{
|
|
if (const Functor* fp = target<Functor>())
|
|
return function_equal(*fp, g);
|
|
else return false;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator!=(Functor g) const
|
|
{
|
|
if (const Functor* fp = target<Functor>())
|
|
return !function_equal(*fp, g);
|
|
else return true;
|
|
}
|
|
#endif
|
|
|
|
public: // should be protected, but GCC 2.95.3 will fail to allow access
|
|
detail::function::any_pointer (*manager)(
|
|
detail::function::any_pointer,
|
|
detail::function::functor_manager_operation_type);
|
|
detail::function::any_pointer functor;
|
|
|
|
private:
|
|
template<typename Functor>
|
|
Functor* get_functor_pointer(detail::function::function_ptr_tag, int)
|
|
{ return reinterpret_cast<Functor*>(&functor.func_ptr); }
|
|
|
|
template<typename Functor, typename Tag>
|
|
Functor* get_functor_pointer(Tag, long)
|
|
{ return static_cast<Functor*>(functor.obj_ptr); }
|
|
|
|
template<typename Functor>
|
|
const Functor*
|
|
get_functor_pointer(detail::function::function_ptr_tag, int) const
|
|
{ return reinterpret_cast<const Functor*>(&functor.func_ptr); }
|
|
|
|
template<typename Functor, typename Tag>
|
|
const Functor* get_functor_pointer(Tag, long) const
|
|
{ return static_cast<const Functor*>(functor.const_obj_ptr); }
|
|
};
|
|
|
|
/**
|
|
* The bad_function_call exception class is thrown when a boost::function
|
|
* object is invoked
|
|
*/
|
|
class bad_function_call : public std::runtime_error
|
|
{
|
|
public:
|
|
bad_function_call() : std::runtime_error("call to empty boost::function") {}
|
|
};
|
|
|
|
#ifndef BOOST_NO_SFINAE
|
|
inline bool operator==(const function_base& f,
|
|
detail::function::useless_clear_type*)
|
|
{
|
|
return f.empty();
|
|
}
|
|
|
|
inline bool operator!=(const function_base& f,
|
|
detail::function::useless_clear_type*)
|
|
{
|
|
return !f.empty();
|
|
}
|
|
|
|
inline bool operator==(detail::function::useless_clear_type*,
|
|
const function_base& f)
|
|
{
|
|
return f.empty();
|
|
}
|
|
|
|
inline bool operator!=(detail::function::useless_clear_type*,
|
|
const function_base& f)
|
|
{
|
|
return !f.empty();
|
|
}
|
|
#endif
|
|
|
|
#ifdef BOOST_NO_SFINAE
|
|
// Comparisons between boost::function objects and arbitrary function objects
|
|
template<typename Functor>
|
|
inline bool operator==(const function_base& f, Functor g)
|
|
{
|
|
typedef mpl::bool_<(is_integral<Functor>::value)> integral;
|
|
return detail::function::compare_equal(f, g, 0, integral());
|
|
}
|
|
|
|
template<typename Functor>
|
|
inline bool operator==(Functor g, const function_base& f)
|
|
{
|
|
typedef mpl::bool_<(is_integral<Functor>::value)> integral;
|
|
return detail::function::compare_equal(f, g, 0, integral());
|
|
}
|
|
|
|
template<typename Functor>
|
|
inline bool operator!=(const function_base& f, Functor g)
|
|
{
|
|
typedef mpl::bool_<(is_integral<Functor>::value)> integral;
|
|
return detail::function::compare_not_equal(f, g, 0, integral());
|
|
}
|
|
|
|
template<typename Functor>
|
|
inline bool operator!=(Functor g, const function_base& f)
|
|
{
|
|
typedef mpl::bool_<(is_integral<Functor>::value)> integral;
|
|
return detail::function::compare_not_equal(f, g, 0, integral());
|
|
}
|
|
#else
|
|
|
|
# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
|
|
// Comparisons between boost::function objects and arbitrary function
|
|
// objects. GCC 3.3 and before has an obnoxious bug that prevents this
|
|
// from working.
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator==(const function_base& f, Functor g)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return function_equal(*fp, g);
|
|
else return false;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator==(Functor g, const function_base& f)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return function_equal(g, *fp);
|
|
else return false;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator!=(const function_base& f, Functor g)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return !function_equal(*fp, g);
|
|
else return true;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator!=(Functor g, const function_base& f)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return !function_equal(g, *fp);
|
|
else return true;
|
|
}
|
|
# endif
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator==(const function_base& f, reference_wrapper<Functor> g)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return fp == g.get_pointer();
|
|
else return false;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator==(reference_wrapper<Functor> g, const function_base& f)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return g.get_pointer() == fp;
|
|
else return false;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator!=(const function_base& f, reference_wrapper<Functor> g)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return fp != g.get_pointer();
|
|
else return true;
|
|
}
|
|
|
|
template<typename Functor>
|
|
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
|
|
operator!=(reference_wrapper<Functor> g, const function_base& f)
|
|
{
|
|
if (const Functor* fp = f.template target<Functor>())
|
|
return g.get_pointer() != fp;
|
|
else return true;
|
|
}
|
|
|
|
#endif // Compiler supporting SFINAE
|
|
|
|
namespace detail {
|
|
namespace function {
|
|
inline bool has_empty_target(const function_base* f)
|
|
{
|
|
return f->empty();
|
|
}
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
|
|
inline bool has_empty_target(const void*)
|
|
{
|
|
return false;
|
|
}
|
|
#else
|
|
inline bool has_empty_target(...)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
} // end namespace function
|
|
} // end namespace detail
|
|
} // end namespace boost
|
|
|
|
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
|
|
#undef BOOST_FUNCTION_COMPARE_TYPE_ID
|
|
|
|
#endif // BOOST_FUNCTION_BASE_HEADER
|