// Function objects that fit in the small-object buffer. static inline void manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag || op == move_functor_tag) { const functor_type* in_functor = reinterpret_cast<const functor_type*>(&in_buffer.data); new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor); if (op == move_functor_tag) { functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } } else if (op == destroy_functor_tag) { // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } else if (op == check_functor_type_tag) { const detail::sp_typeinfo& check_type = *out_buffer.type.type; 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 = &BOOST_SP_TYPEID(Functor); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } }
// Function objects that require heap allocation static inline void manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { if (op == clone_functor_tag) { // Clone the functor // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. const functor_type* f = (const functor_type*)(in_buffer.obj_ptr); functor_type* new_f = new functor_type(*f); out_buffer.obj_ptr = new_f; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor pointer type */ functor_type* f = static_cast<functor_type*>(out_buffer.obj_ptr); delete f; out_buffer.obj_ptr = 0; } else /* op == check_functor_type_tag */ { const BOOST_FUNCTION_STD_NS::type_info& check_type = *static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr); if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) out_buffer.obj_ptr = in_buffer.obj_ptr; else out_buffer.obj_ptr = 0; } }
// Function objects that require heap allocation static inline void manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { if (op == clone_functor_tag) { // Clone the functor // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. const functor_type* f = (const functor_type*)(in_buffer.obj_ptr); functor_type* new_f = new functor_type(*f); out_buffer.obj_ptr = new_f; } else if (op == move_functor_tag) { out_buffer.obj_ptr = in_buffer.obj_ptr; in_buffer.obj_ptr = 0; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor pointer type */ functor_type* f = static_cast<functor_type*>(out_buffer.obj_ptr); delete f; out_buffer.obj_ptr = 0; } else if (op == check_functor_type_tag) { const detail::sp_typeinfo& check_type = *out_buffer.type.type; 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 = &BOOST_SP_TYPEID(Functor); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } }
// Function objects that fit in the small-object buffer. static inline void manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag || op == move_functor_tag) { const functor_type* in_functor = reinterpret_cast<const functor_type*>(&in_buffer.data); new ((void*)&out_buffer.data) functor_type(*in_functor); if (op == move_functor_tag) { reinterpret_cast<functor_type*>(&in_buffer.data)->~Functor(); } } else if (op == destroy_functor_tag) { // 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 = *out_buffer.type.type; if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, 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.const_qualified = false; out_buffer.type.volatile_qualified = false; } }
static inline void get(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { switch (op) { case clone_functor_tag: out_buffer.obj_ptr = in_buffer.obj_ptr; return; case destroy_functor_tag: out_buffer.obj_ptr = 0; return; case check_functor_type_tag: { // DPG TBD: Since we're only storing a pointer, it's // possible that the user could ask for a base class or // derived class. Is that okay? const BOOST_FUNCTION_STD_NS::type_info& check_type = *static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr); if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))) out_buffer.obj_ptr = in_buffer.obj_ptr; else out_buffer.obj_ptr = 0; } return; case get_functor_type_tag: out_buffer.const_obj_ptr = &typeid(F); return; } }
// Function objects that require heap allocation static inline void manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { #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) { // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. const functor_type* f = (const functor_type*)(in_buffer.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 out_buffer.obj_ptr = new_f; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor pointer type */ functor_type* f = static_cast<functor_type*>(out_buffer.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 out_buffer.obj_ptr = 0; } else /* op == check_functor_type_tag */ { const std::type_info& check_type = *static_cast<const std::type_info*>(out_buffer.const_obj_ptr); if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) out_buffer.obj_ptr = in_buffer.obj_ptr; else out_buffer.obj_ptr = 0; } }
/* 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()); } }
// Function objects that require heap allocation static inline void manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::false_) { typedef functor_wrapper<Functor,Allocator> functor_wrapper_type; typedef typename Allocator::template rebind<functor_wrapper_type>::other wrapper_allocator_type; typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; if (op == clone_functor_tag) { // Clone the functor // GCC 2.95.3 gets the CV qualifiers wrong here, so we // can't do the static_cast that we should do. const functor_wrapper_type* f = static_cast<const functor_wrapper_type*>(in_buffer.obj_ptr); wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f)); wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); wrapper_allocator.construct(copy, *f); // Get back to the original pointer type functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy); out_buffer.obj_ptr = new_f; } else if (op == move_functor_tag) { out_buffer.obj_ptr = in_buffer.obj_ptr; in_buffer.obj_ptr = 0; } else if (op == destroy_functor_tag) { /* Cast from the void pointer to the functor_wrapper_type */ functor_wrapper_type* victim = static_cast<functor_wrapper_type*>(in_buffer.obj_ptr); wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*victim)); wrapper_allocator.destroy(victim); wrapper_allocator.deallocate(victim,1); out_buffer.obj_ptr = 0; } else if (op == check_functor_type_tag) { const detail::sp_typeinfo& check_type = *out_buffer.type.type; 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 = &BOOST_SP_TYPEID(Functor); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } }
// Function pointers static inline void manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag) out_buffer.func_ptr = in_buffer.func_ptr; else if (op == destroy_functor_tag) out_buffer.func_ptr = 0; else /* op == check_functor_type_tag */ { const BOOST_FUNCTION_STD_NS::type_info& check_type = *static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr); if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) out_buffer.obj_ptr = &in_buffer.func_ptr; else out_buffer.obj_ptr = 0; } }
static inline void manage(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { switch (op) { case clone_functor_tag: out_buffer.obj_ref = in_buffer.obj_ref; return; case move_functor_tag: out_buffer.obj_ref = in_buffer.obj_ref; in_buffer.obj_ref.obj_ptr = 0; return; case destroy_functor_tag: out_buffer.obj_ref.obj_ptr = 0; return; case check_functor_type_tag: { 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, BOOST_SP_TYPEID(F)) && (!in_buffer.obj_ref.is_const_qualified || out_buffer.type.const_qualified) && (!in_buffer.obj_ref.is_volatile_qualified || out_buffer.type.volatile_qualified)) out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr; else out_buffer.obj_ptr = 0; } return; case get_functor_type_tag: 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; } }
// Function objects that fit in the small-object buffer. static inline void manager(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op, mpl::true_) { if (op == clone_functor_tag) { const functor_type* in_functor = reinterpret_cast<const functor_type*>(&in_buffer.data); new ((void*)&out_buffer.data) functor_type(*in_functor); } else if (op == destroy_functor_tag) { // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor(); } else /* op == check_functor_type_tag */ { const std::type_info& check_type = *static_cast<const std::type_info*>(out_buffer.const_obj_ptr); if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) out_buffer.obj_ptr = &in_buffer.data; else out_buffer.obj_ptr = 0; } }
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)); }
// Function pointers static inline void manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, functor_manager_operation_type op) { if (op == clone_functor_tag) out_buffer.func_ptr = in_buffer.func_ptr; else if (op == move_functor_tag) { out_buffer.func_ptr = in_buffer.func_ptr; in_buffer.func_ptr = 0; } else if (op == destroy_functor_tag) out_buffer.func_ptr = 0; else if (op == check_functor_type_tag) { const detail::sp_typeinfo& check_type = *out_buffer.type.type; 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 = &BOOST_SP_TYPEID(Functor); out_buffer.type.const_qualified = false; out_buffer.type.volatile_qualified = false; } }