#include <string>
#include <memory>
#include <new>
-#include <typeinfo>
#include <boost/config.hpp>
+#include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp>
+#include <boost/integer.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_volatile.hpp>
#endif
// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
-#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE
+#ifdef BOOST_NO_STD_TYPEINFO
// Embedded VC++ does not have type_info in namespace std
# define BOOST_FUNCTION_STD_NS
#else
// 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) \
+#if defined( BOOST_NO_TYPEID )
+# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#elif (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips))
# include <cstring>
// For pointers to std::type_info objects
struct type_t {
// (get_functor_type_tag, check_functor_type_tag).
- const BOOST_FUNCTION_STD_NS::type_info* type;
+ const detail::sp_typeinfo* type;
// Whether the type is const-qualified.
bool const_qualified;
case check_functor_type_tag:
{
- const BOOST_FUNCTION_STD_NS::type_info& check_type
+ const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
// Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away.
- if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
+ if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F))
&& (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified
return;
case get_functor_type_tag:
- out_buffer.type.type = &typeid(F);
+ out_buffer.type.type = &BOOST_SP_TYPEID(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
return;
A(a)
{
}
+
+ functor_wrapper(const functor_wrapper& f) :
+ F(static_cast<const F&>(f)),
+ A(static_cast<const A&>(f))
+ {
+ }
};
/**
} else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) {
- const BOOST_FUNCTION_STD_NS::type_info& check_type
+ const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
- if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
+ if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
- out_buffer.type.type = &typeid(Functor);
+ out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} else if (op == check_functor_type_tag) {
- const BOOST_FUNCTION_STD_NS::type_info& check_type
+ const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
- if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
+ if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = &in_buffer.data;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
- out_buffer.type.type = &typeid(Functor);
+ out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
delete f;
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
- const BOOST_FUNCTION_STD_NS::type_info& check_type
+ const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
- if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
+ if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
- out_buffer.type.type = &typeid(Functor);
+ out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
- out_buffer.type.type = &typeid(functor_type);
+ out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
return;
wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
- const BOOST_FUNCTION_STD_NS::type_info& check_type
+ const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
- if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
+ if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
- out_buffer.type.type = &typeid(Functor);
+ out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
- out_buffer.type.type = &typeid(functor_type);
+ out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
return;
/** Determine if the function is empty (i.e., has no target). */
bool empty() const { return !vtable; }
- /** Retrieve the type of the stored function object, or typeid(void)
+ /** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void)
if this is empty. */
- const BOOST_FUNCTION_STD_NS::type_info& target_type() const
+ const detail::sp_typeinfo& target_type() const
{
- if (!vtable) return typeid(void);
+ if (!vtable) return BOOST_SP_TYPEID(void);
detail::function::function_buffer type;
- vtable->manager(functor, type, detail::function::get_functor_type_tag);
+ get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
return *type.type.type;
}
if (!vtable) return 0;
detail::function::function_buffer type_result;
- type_result.type.type = &typeid(Functor);
+ type_result.type.type = &BOOST_SP_TYPEID(Functor);
type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
- vtable->manager(functor, type_result,
+ get_vtable()->manager(functor, type_result,
detail::function::check_functor_type_tag);
return static_cast<Functor*>(type_result.obj_ptr);
}
if (!vtable) return 0;
detail::function::function_buffer type_result;
- type_result.type.type = &typeid(Functor);
+ type_result.type.type = &BOOST_SP_TYPEID(Functor);
type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
- vtable->manager(functor, type_result,
+ get_vtable()->manager(functor, type_result,
detail::function::check_functor_type_tag);
// GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do.
#endif
public: // should be protected, but GCC 2.95.3 will fail to allow access
+ detail::function::vtable_base* get_vtable() const {
+ return reinterpret_cast<detail::function::vtable_base*>(
+ reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
+ }
+
+ bool has_trivial_copy_and_destroy() const {
+ return reinterpret_cast<std::size_t>(vtable) & 0x01;
+ }
+
detail::function::vtable_base* vtable;
mutable detail::function::function_buffer functor;
};
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
#undef BOOST_FUNCTION_COMPARE_TYPE_ID
+#if defined(BOOST_MSVC)
+# pragma warning( pop )
+#endif
+
#endif // BOOST_FUNCTION_BASE_HEADER