Пример #1
0
        // 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;
   }
 }
Пример #3
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;
   }
 }
Пример #4
0
        // 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;
          }
        }
Пример #6
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_)
        {
#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());
     }
 }
Пример #8
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_)
        {
          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;
   }
 }
Пример #10
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;
          }
        }
Пример #11
0
 // 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;
   }
 }
Пример #12
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));
        }
Пример #13
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;
   }
 }