virtual_functions.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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/class.hpp>
  6. #include <boost/python/module.hpp>
  7. #include <boost/python/def.hpp>
  8. #include <boost/python/return_internal_reference.hpp>
  9. #include <boost/python/call_method.hpp>
  10. #include <boost/ref.hpp>
  11. #include <boost/utility.hpp>
  12. #define BOOST_ENABLE_ASSERT_HANDLER
  13. #include <boost/assert.hpp>
  14. using namespace boost::python;
  15. struct X
  16. {
  17. explicit X(int x) : x(x), magic(7654321) { ++counter; }
  18. X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
  19. virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
  20. void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
  21. int value() const { BOOST_ASSERT(magic == 7654321); return x; }
  22. static int count() { return counter; }
  23. private:
  24. void operator=(X const&);
  25. private:
  26. int x;
  27. long magic;
  28. static int counter;
  29. };
  30. struct Y : X
  31. {
  32. Y(int x) : X(x) {};
  33. };
  34. struct abstract : X
  35. {
  36. abstract(int x) : X(x) {};
  37. int call_f(Y const& y) { return f(y); }
  38. virtual int f(Y const& y) = 0;
  39. abstract& call_g(Y const& y) { return g(y); }
  40. virtual abstract& g(Y const& y) = 0;
  41. };
  42. struct concrete : X
  43. {
  44. concrete(int x) : X(x) {};
  45. int call_f(Y const& y) { return f(y); }
  46. virtual int f(Y const& y) { set(y.value()); return y.value(); }
  47. };
  48. struct abstract_callback : abstract
  49. {
  50. abstract_callback(PyObject* p, int x)
  51. : abstract(x), self(p)
  52. {}
  53. int f(Y const& y)
  54. {
  55. return call_method<int>(self, "f", boost::ref(y));
  56. }
  57. abstract& g(Y const& y)
  58. {
  59. return call_method<abstract&>(self, "g", boost::ref(y));
  60. }
  61. PyObject* self;
  62. };
  63. struct concrete_callback : concrete
  64. {
  65. concrete_callback(PyObject* p, int x)
  66. : concrete(x), self(p)
  67. {}
  68. concrete_callback(PyObject* p, concrete const& x)
  69. : concrete(x), self(p)
  70. {}
  71. int f(Y const& y)
  72. {
  73. return call_method<int>(self, "f", boost::ref(y));
  74. }
  75. int f_impl(Y const& y)
  76. {
  77. return this->concrete::f(y);
  78. }
  79. PyObject* self;
  80. };
  81. int X::counter;
  82. BOOST_PYTHON_MODULE(virtual_functions_ext)
  83. {
  84. class_<concrete, concrete_callback>("concrete", init<int>())
  85. .def("value", &concrete::value)
  86. .def("set", &concrete::set)
  87. .def("call_f", &concrete::call_f)
  88. .def("f", &concrete_callback::f_impl)
  89. ;
  90. class_<abstract, boost::noncopyable, abstract_callback
  91. >("abstract", init<int>())
  92. .def("value", &abstract::value)
  93. .def("call_f", &abstract::call_f)
  94. .def("call_g", &abstract::call_g, return_internal_reference<>())
  95. .def("set", &abstract::set)
  96. ;
  97. class_<Y>("Y", init<int>())
  98. .def("value", &Y::value)
  99. .def("set", &Y::set)
  100. ;
  101. }
  102. #include "module_tail.cpp"