polymorphism2.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #include <boost/python/module.hpp>
  6. #include <boost/python/class.hpp>
  7. #include <boost/python/return_value_policy.hpp>
  8. #include <boost/python/manage_new_object.hpp>
  9. #include <boost/python/reference_existing_object.hpp>
  10. #include <boost/python/pure_virtual.hpp>
  11. #include <boost/python/wrapper.hpp>
  12. #include <boost/python/def.hpp>
  13. #include <boost/python/call.hpp>
  14. #include <boost/utility.hpp>
  15. #include <memory>
  16. #ifdef HELD_BY_AUTO_PTR
  17. # define HELD_PTR(X) , std::auto_ptr< X >
  18. #else
  19. # define HELD_PTR(X)
  20. #endif
  21. using namespace boost::python;
  22. struct P
  23. {
  24. virtual ~P(){}
  25. virtual char const* f() = 0;
  26. char const* g() { return "P::g()"; }
  27. };
  28. struct PCallback : P, wrapper<P>
  29. {
  30. char const* f()
  31. {
  32. #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  33. return call<char const*>(this->get_override("f").ptr());
  34. #else
  35. return this->get_override("f")();
  36. #endif
  37. }
  38. };
  39. struct Q : virtual P
  40. {
  41. char const* f() { return "Q::f()"; }
  42. };
  43. struct A
  44. {
  45. virtual ~A(){}
  46. virtual char const* f() { return "A::f()"; }
  47. };
  48. struct ACallback : A, wrapper<A>
  49. {
  50. char const* f()
  51. {
  52. if (override f = this->get_override("f"))
  53. #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  54. return call<char const*>(f.ptr());
  55. #else
  56. return f();
  57. #endif
  58. return A::f();
  59. }
  60. char const* default_f() { return this->A::f(); }
  61. };
  62. struct B : A
  63. {
  64. virtual char const* f() { return "B::f()"; }
  65. };
  66. struct C : A
  67. {
  68. virtual char const* f() { return "C::f()"; }
  69. };
  70. struct D : A
  71. {
  72. virtual char const* f() { return "D::f()"; }
  73. char const* g() { return "D::g()"; }
  74. };
  75. struct DCallback : D, wrapper<D>
  76. {
  77. char const* f()
  78. {
  79. if (override f = this->get_override("f"))
  80. #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  81. return call<char const*>(f.ptr());
  82. #else
  83. return f();
  84. #endif
  85. //else
  86. return D::f();
  87. }
  88. };
  89. A& getBCppObj ()
  90. {
  91. static B b;
  92. return b;
  93. }
  94. char const* call_f(A& a) { return a.f(); }
  95. A* factory(unsigned choice)
  96. {
  97. switch (choice % 3)
  98. {
  99. case 0: return new A;
  100. break;
  101. case 1: return new B;
  102. break;
  103. default: return new C;
  104. break;
  105. }
  106. }
  107. C& getCCppObj ()
  108. {
  109. static C c;
  110. return c;
  111. }
  112. A* pass_a(A* x) { return x; }
  113. #ifdef HELD_BY_AUTO_PTR
  114. BOOST_PYTHON_MODULE_INIT(polymorphism2_auto_ptr_ext)
  115. #else
  116. BOOST_PYTHON_MODULE_INIT(polymorphism2_ext)
  117. #endif
  118. {
  119. class_<ACallback HELD_PTR(A),boost::noncopyable>("A")
  120. .def("f", &A::f, &ACallback::default_f)
  121. ;
  122. def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
  123. class_<C HELD_PTR(C),bases<A>,boost::noncopyable>("C")
  124. .def("f", &C::f)
  125. ;
  126. class_<DCallback HELD_PTR(D),bases<A>,boost::noncopyable>("D")
  127. .def("f", &D::f)
  128. .def("g", &D::g)
  129. ;
  130. def("pass_a", &pass_a, return_internal_reference<>());
  131. def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
  132. def("factory", factory, return_value_policy<manage_new_object>());
  133. def("call_f", call_f);
  134. class_<PCallback,boost::noncopyable>("P")
  135. .def("f", pure_virtual(&P::f))
  136. ;
  137. class_<Q HELD_PTR(Q), bases<P> >("Q")
  138. .def("g", &P::g) // make sure virtual inheritance doesn't interfere
  139. ;
  140. }
  141. //#include "module_tail.cpp"