inheritance.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef INHERITANCE_DWA200216_HPP
  6. # define INHERITANCE_DWA200216_HPP
  7. # include <boost/python/type_id.hpp>
  8. # include <boost/shared_ptr.hpp>
  9. # include <boost/mpl/if.hpp>
  10. # include <boost/detail/workaround.hpp>
  11. # include <boost/python/detail/type_traits.hpp>
  12. namespace boost { namespace python { namespace objects {
  13. typedef type_info class_id;
  14. using python::type_id;
  15. // Types used to get address and id of most derived type
  16. typedef std::pair<void*,class_id> dynamic_id_t;
  17. typedef dynamic_id_t (*dynamic_id_function)(void*);
  18. BOOST_PYTHON_DECL void register_dynamic_id_aux(
  19. class_id static_id, dynamic_id_function get_dynamic_id);
  20. BOOST_PYTHON_DECL void add_cast(
  21. class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast);
  22. //
  23. // a generator with an execute() function which, given a source type
  24. // and a pointer to an object of that type, returns its most-derived
  25. // /reachable/ type identifier and object pointer.
  26. //
  27. // first, the case where T has virtual functions
  28. template <class T>
  29. struct polymorphic_id_generator
  30. {
  31. static dynamic_id_t execute(void* p_)
  32. {
  33. T* p = static_cast<T*>(p_);
  34. return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
  35. }
  36. };
  37. // now, the non-polymorphic case.
  38. template <class T>
  39. struct non_polymorphic_id_generator
  40. {
  41. static dynamic_id_t execute(void* p_)
  42. {
  43. return std::make_pair(p_, python::type_id<T>());
  44. }
  45. };
  46. // Now the generalized selector
  47. template <class T>
  48. struct dynamic_id_generator
  49. : mpl::if_<
  50. boost::python::detail::is_polymorphic<T>
  51. , boost::python::objects::polymorphic_id_generator<T>
  52. , boost::python::objects::non_polymorphic_id_generator<T>
  53. >
  54. {};
  55. // Register the dynamic id function for T with the type-conversion
  56. // system.
  57. template <class T>
  58. void register_dynamic_id(T* = 0)
  59. {
  60. typedef typename dynamic_id_generator<T>::type generator;
  61. register_dynamic_id_aux(
  62. python::type_id<T>(), &generator::execute);
  63. }
  64. //
  65. // a generator with an execute() function which, given a void*
  66. // pointing to an object of type Source will attempt to convert it to
  67. // an object of type Target.
  68. //
  69. template <class Source, class Target>
  70. struct dynamic_cast_generator
  71. {
  72. static void* execute(void* source)
  73. {
  74. return dynamic_cast<Target*>(
  75. static_cast<Source*>(source));
  76. }
  77. };
  78. template <class Source, class Target>
  79. struct implicit_cast_generator
  80. {
  81. static void* execute(void* source)
  82. {
  83. Target* result = static_cast<Source*>(source);
  84. return result;
  85. }
  86. };
  87. template <class Source, class Target>
  88. struct cast_generator
  89. : mpl::if_<
  90. boost::python::detail::is_base_and_derived<Target,Source>
  91. , implicit_cast_generator<Source,Target>
  92. , dynamic_cast_generator<Source,Target>
  93. >
  94. {
  95. };
  96. template <class Source, class Target>
  97. inline void register_conversion(
  98. bool is_downcast = ::boost::is_base_and_derived<Source,Target>::value
  99. // These parameters shouldn't be used; they're an MSVC bug workaround
  100. , Source* = 0, Target* = 0)
  101. {
  102. typedef typename cast_generator<Source,Target>::type generator;
  103. add_cast(
  104. python::type_id<Source>()
  105. , python::type_id<Target>()
  106. , &generator::execute
  107. , is_downcast
  108. );
  109. }
  110. }}} // namespace boost::python::object
  111. #endif // INHERITANCE_DWA200216_HPP