• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <memory>
17 
18 #ifdef HELD_BY_AUTO_PTR
19 # define HELD_PTR(X) , std::auto_ptr< X >
20 #else
21 # define HELD_PTR(X)
22 #endif
23 
24 using namespace boost::python;
25 
26 struct P
27 {
~PP28     virtual ~P(){}
29     virtual char const* f() = 0;
gP30     char const* g() { return "P::g()"; }
31 };
32 
33 struct PCallback : P, wrapper<P>
34 {
fPCallback35     char const* f()
36     {
37 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
38         return call<char const*>(this->get_override("f").ptr());
39 #else
40         return this->get_override("f")();
41 #endif
42     }
43 };
44 
45 struct Q : virtual P
46 {
fQ47     char const* f() { return "Q::f()"; }
48 };
49 
50 struct A
51 {
~AA52     virtual ~A(){}
fA53     virtual char const* f() { return "A::f()"; }
54 };
55 
56 struct ACallback :  A, wrapper<A>
57 {
fACallback58     char const* f()
59     {
60         if (override f = this->get_override("f"))
61 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
62             return call<char const*>(f.ptr());
63 #else
64             return f();
65 #endif
66 
67         return A::f();
68     }
69 
default_fACallback70     char const* default_f() { return this->A::f(); }
71 };
72 
73 struct B : A
74 {
fB75     virtual char const* f() { return "B::f()"; }
76 };
77 
78 struct C : A
79 {
fC80     virtual char const* f() { return "C::f()"; }
81 };
82 
83 struct D : A
84 {
fD85     virtual char const* f() { return "D::f()"; }
gD86     char const* g() { return "D::g()"; }
87 };
88 
89 struct DCallback :  D,  wrapper<D>
90 {
fDCallback91     char const* f()
92     {
93         if (override f = this->get_override("f"))
94 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
95             return call<char const*>(f.ptr());
96 #else
97             return f();
98 #endif
99         //else
100             return D::f();
101     }
102 };
103 
104 
getBCppObj()105 A& getBCppObj ()
106 {
107     static B b;
108     return b;
109 }
110 
call_f(A & a)111 char const* call_f(A& a) { return a.f(); }
112 
factory(unsigned choice)113 A* factory(unsigned choice)
114 {
115     switch (choice % 3)
116     {
117     case 0: return new A;
118         break;
119     case 1: return new B;
120         break;
121     default: return new C;
122         break;
123     }
124 }
125 
getCCppObj()126 C& getCCppObj ()
127 {
128     static C c;
129     return c;
130 }
131 
pass_a(A * x)132 A* pass_a(A* x) { return x; }
133 
134 #ifdef HELD_BY_AUTO_PTR
BOOST_PYTHON_MODULE_INIT(polymorphism2_auto_ptr_ext)135 BOOST_PYTHON_MODULE_INIT(polymorphism2_auto_ptr_ext)
136 #else
137 BOOST_PYTHON_MODULE_INIT(polymorphism2_ext)
138 #endif
139 {
140     class_<ACallback HELD_PTR(A),boost::noncopyable>("A")
141         .def("f", &A::f, &ACallback::default_f)
142         ;
143 
144     def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
145 
146     class_<C HELD_PTR(C),bases<A>,boost::noncopyable>("C")
147         .def("f", &C::f)
148         ;
149 
150     class_<DCallback HELD_PTR(D),bases<A>,boost::noncopyable>("D")
151         .def("f", &D::f)
152         .def("g", &D::g)
153         ;
154 
155     def("pass_a", &pass_a,  return_internal_reference<>());
156 
157     def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
158 
159     def("factory", factory, return_value_policy<manage_new_object>());
160 
161     def("call_f", call_f);
162 
163     class_<PCallback,boost::noncopyable>("P")
164         .def("f", pure_virtual(&P::f))
165         ;
166 
167     class_<Q HELD_PTR(Q), bases<P> >("Q")
168         .def("g", &P::g) // make sure virtual inheritance doesn't interfere
169         ;
170 }
171 
172 //#include "module_tail.cpp"
173