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/call_method.hpp>
11 #include <boost/python/pure_virtual.hpp>
12 #include <boost/python/def.hpp>
13 #include <boost/utility.hpp>
14
15 using namespace boost::python;
16
17 struct Callback
18 {
CallbackCallback19 Callback(PyObject* o) : mSelf(o) {}
20 PyObject* mSelf;
21 };
22
23 struct P
24 {
~PP25 virtual ~P(){}
26 virtual std::string f() = 0;
gP27 std::string g() { return "P::g()"; }
28 };
29
30 struct PCallback : P, Callback
31 {
PCallbackPCallback32 PCallback (PyObject* self) : Callback(self) {}
33
fPCallback34 std::string f()
35 {
36 return call_method<std::string>(mSelf, "f");
37 }
38 };
39
40 struct Q : virtual P
41 {
fQ42 std::string f() { return "Q::f()"; }
43 };
44
45 struct A
46 {
~AA47 virtual ~A(){}
fA48 virtual std::string f() { return "A::f()"; }
49 };
50
51 struct ACallback : A, Callback
52 {
ACallbackACallback53 ACallback (PyObject* self) : Callback(self) {}
54
55
fACallback56 std::string f()
57 {
58 return call_method<std::string>(mSelf, "f");
59 }
60
default_fACallback61 std::string default_f()
62 {
63 return A::f();
64 }
65 };
66
67 struct B : A
68 {
fB69 virtual std::string f() { return "B::f()"; }
70 };
71
72 struct C : A
73 {
fC74 virtual std::string f() { return "C::f()"; }
75 };
76
77 struct D : A
78 {
fD79 virtual std::string f() { return "D::f()"; }
gD80 std::string g() { return "D::g()"; }
81 };
82
83 struct DCallback : D, Callback
84 {
DCallbackDCallback85 DCallback (PyObject* self) : Callback(self) {}
86
fDCallback87 std::string f()
88 {
89 return call_method<std::string>(mSelf, "f");
90 }
91
default_fDCallback92 std::string default_f()
93 {
94 return A::f();
95 }
96 };
97
98
getBCppObj()99 A& getBCppObj ()
100 {
101 static B b;
102 return b;
103 }
104
call_f(A & a)105 std::string call_f(A& a) { return a.f(); }
106
factory(unsigned choice)107 A* factory(unsigned choice)
108 {
109 switch (choice % 3)
110 {
111 case 0: return new A;
112 break;
113 case 1: return new B;
114 break;
115 default: return new C;
116 break;
117 }
118 }
119
getCCppObj()120 C& getCCppObj ()
121 {
122 static C c;
123 return c;
124 }
125
pass_a(A * x)126 A* pass_a(A* x) { return x; }
127
BOOST_PYTHON_MODULE_INIT(polymorphism_ext)128 BOOST_PYTHON_MODULE_INIT(polymorphism_ext)
129 {
130 class_<A,boost::noncopyable,ACallback>("A")
131 .def("f", &A::f, &ACallback::default_f)
132 ;
133
134 def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
135
136 class_<C,bases<A>,boost::noncopyable>("C")
137 .def("f", &C::f)
138 ;
139
140 class_<D,bases<A>,DCallback,boost::noncopyable>("D")
141 .def("f", &D::f, &DCallback::default_f)
142 .def("g", &D::g)
143 ;
144
145 def("pass_a", &pass_a, return_internal_reference<>());
146
147 def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
148
149 def("factory", factory, return_value_policy<manage_new_object>());
150
151 def("call_f", call_f);
152
153 class_<P,boost::noncopyable,PCallback>("P")
154 .def("f", pure_virtual(&P::f))
155 ;
156
157 class_<Q, bases<P> >("Q")
158 .def("g", &P::g) // make sure virtual inheritance doesn't interfere
159 ;
160 }
161
162 //#include "module_tail.cpp"
163