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 + -
显示快捷键?