Chris@16: // Copyright David Abrahams 2002. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: #ifndef INHERITANCE_DWA200216_HPP Chris@16: # define INHERITANCE_DWA200216_HPP Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: namespace boost { namespace python { namespace objects { Chris@16: Chris@16: typedef type_info class_id; Chris@16: using python::type_id; Chris@16: Chris@16: // Types used to get address and id of most derived type Chris@16: typedef std::pair dynamic_id_t; Chris@16: typedef dynamic_id_t (*dynamic_id_function)(void*); Chris@16: Chris@16: BOOST_PYTHON_DECL void register_dynamic_id_aux( Chris@16: class_id static_id, dynamic_id_function get_dynamic_id); Chris@16: Chris@16: BOOST_PYTHON_DECL void add_cast( Chris@16: class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast); Chris@16: Chris@16: // Chris@16: // a generator with an execute() function which, given a source type Chris@16: // and a pointer to an object of that type, returns its most-derived Chris@16: // /reachable/ type identifier and object pointer. Chris@16: // Chris@16: Chris@16: // first, the case where T has virtual functions Chris@16: template Chris@16: struct polymorphic_id_generator Chris@16: { Chris@16: static dynamic_id_t execute(void* p_) Chris@16: { Chris@16: T* p = static_cast(p_); Chris@16: return std::make_pair(dynamic_cast(p), class_id(typeid(*p))); Chris@16: } Chris@16: }; Chris@16: Chris@16: // now, the non-polymorphic case. Chris@16: template Chris@16: struct non_polymorphic_id_generator Chris@16: { Chris@16: static dynamic_id_t execute(void* p_) Chris@16: { Chris@16: return std::make_pair(p_, python::type_id()); Chris@16: } Chris@16: }; Chris@16: Chris@16: // Now the generalized selector Chris@16: template Chris@16: struct dynamic_id_generator Chris@16: : mpl::if_< Chris@16: boost::is_polymorphic Chris@16: , boost::python::objects::polymorphic_id_generator Chris@16: , boost::python::objects::non_polymorphic_id_generator Chris@16: > Chris@16: {}; Chris@16: Chris@16: // Register the dynamic id function for T with the type-conversion Chris@16: // system. Chris@16: template Chris@16: void register_dynamic_id(T* = 0) Chris@16: { Chris@16: typedef typename dynamic_id_generator::type generator; Chris@16: register_dynamic_id_aux( Chris@16: python::type_id(), &generator::execute); Chris@16: } Chris@16: Chris@16: // Chris@16: // a generator with an execute() function which, given a void* Chris@16: // pointing to an object of type Source will attempt to convert it to Chris@16: // an object of type Target. Chris@16: // Chris@16: Chris@16: template Chris@16: struct dynamic_cast_generator Chris@16: { Chris@16: static void* execute(void* source) Chris@16: { Chris@16: return dynamic_cast( Chris@16: static_cast(source)); Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct implicit_cast_generator Chris@16: { Chris@16: static void* execute(void* source) Chris@16: { Chris@16: Target* result = static_cast(source); Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct cast_generator Chris@16: : mpl::if_< Chris@16: is_base_and_derived Chris@16: , implicit_cast_generator Chris@16: , dynamic_cast_generator Chris@16: > Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: inline void register_conversion( Chris@16: bool is_downcast = ::boost::is_base_and_derived::value Chris@16: // These parameters shouldn't be used; they're an MSVC bug workaround Chris@16: , Source* = 0, Target* = 0) Chris@16: { Chris@16: typedef typename cast_generator::type generator; Chris@16: Chris@16: add_cast( Chris@16: python::type_id() Chris@16: , python::type_id() Chris@16: , &generator::execute Chris@16: , is_downcast Chris@16: ); Chris@16: } Chris@16: Chris@16: }}} // namespace boost::python::object Chris@16: Chris@16: #endif // INHERITANCE_DWA200216_HPP