inheritance.hpp 3.5 KB

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