Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/python/object/inheritance.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright David Abrahams 2002.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef INHERITANCE_DWA200216_HPP
0006 # define INHERITANCE_DWA200216_HPP
0007 
0008 # include <boost/python/type_id.hpp>
0009 # include <boost/shared_ptr.hpp>
0010 # include <boost/mpl/if.hpp>
0011 # include <boost/detail/workaround.hpp>
0012 # include <boost/python/detail/type_traits.hpp>
0013 
0014 namespace boost { namespace python { namespace objects {
0015 
0016 typedef type_info class_id;
0017 using python::type_id;
0018 
0019 // Types used to get address and id of most derived type
0020 typedef std::pair<void*,class_id> dynamic_id_t;
0021 typedef dynamic_id_t (*dynamic_id_function)(void*);
0022 
0023 BOOST_PYTHON_DECL void register_dynamic_id_aux(
0024     class_id static_id, dynamic_id_function get_dynamic_id);
0025 
0026 BOOST_PYTHON_DECL void add_cast(
0027     class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast);
0028 
0029 //
0030 // a generator with an execute() function which, given a source type
0031 // and a pointer to an object of that type, returns its most-derived
0032 // /reachable/ type identifier and object pointer.
0033 //
0034 
0035 // first, the case where T has virtual functions
0036 template <class T>
0037 struct polymorphic_id_generator
0038 {
0039     static dynamic_id_t execute(void* p_)
0040     {
0041         T* p = static_cast<T*>(p_);
0042         return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
0043     }
0044 };
0045 
0046 // now, the non-polymorphic case.
0047 template <class T>
0048 struct non_polymorphic_id_generator
0049 {
0050     static dynamic_id_t execute(void* p_)
0051     {
0052         return std::make_pair(p_, python::type_id<T>());
0053     }
0054 };
0055 
0056 // Now the generalized selector
0057 template <class T>
0058 struct dynamic_id_generator
0059   : mpl::if_<
0060         boost::python::detail::is_polymorphic<T>
0061         , boost::python::objects::polymorphic_id_generator<T>
0062         , boost::python::objects::non_polymorphic_id_generator<T>
0063     >
0064 {};
0065 
0066 // Register the dynamic id function for T with the type-conversion
0067 // system.
0068 template <class T>
0069 void register_dynamic_id(T* = 0)
0070 {
0071     typedef typename dynamic_id_generator<T>::type generator;
0072     register_dynamic_id_aux(
0073         python::type_id<T>(), &generator::execute);
0074 }
0075 
0076 //
0077 // a generator with an execute() function which, given a void*
0078 // pointing to an object of type Source will attempt to convert it to
0079 // an object of type Target.
0080 //
0081 
0082 template <class Source, class Target>
0083 struct dynamic_cast_generator
0084 {
0085     static void* execute(void* source)
0086     {
0087         return dynamic_cast<Target*>(
0088             static_cast<Source*>(source));
0089     }
0090         
0091 };
0092 
0093 template <class Source, class Target>
0094 struct implicit_cast_generator
0095 {
0096     static void* execute(void* source)
0097     {
0098         Target* result = static_cast<Source*>(source);
0099         return result;
0100     }
0101 };
0102 
0103 template <class Source, class Target>
0104 struct cast_generator
0105   : mpl::if_<
0106         boost::python::detail::is_base_and_derived<Target,Source>
0107       , implicit_cast_generator<Source,Target>
0108       , dynamic_cast_generator<Source,Target>
0109     >
0110 {
0111 };
0112 
0113 template <class Source, class Target>
0114 inline void register_conversion(
0115     bool is_downcast = ::boost::is_base_and_derived<Source,Target>::value
0116     // These parameters shouldn't be used; they're an MSVC bug workaround
0117     , Source* = 0, Target* = 0)
0118 {
0119     typedef typename cast_generator<Source,Target>::type generator;
0120 
0121     add_cast(
0122         python::type_id<Source>()
0123       , python::type_id<Target>()
0124       , &generator::execute
0125       , is_downcast
0126     );
0127 }
0128 
0129 }}} // namespace boost::python::object
0130 
0131 #endif // INHERITANCE_DWA200216_HPP