function_base.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 661 行 · 第 1/2 页

HPP
661
字号
// 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;#elsetemplate<typename Signature, typename Allocator = std::allocator<void> >class function;#endiftemplate<typename Signature, typename Allocator>inline void swap(function<Signature, Allocator>& f1,                 function<Signature, Allocator>& f2){  f1.swap(f2);}} // end namespace boost#endif // have partial specializationnamespace 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>)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?