• 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 
6 #include <boost/python/class.hpp>
7 #include <boost/python/module.hpp>
8 #include <boost/python/def.hpp>
9 #include <boost/python/return_internal_reference.hpp>
10 #include <boost/python/call_method.hpp>
11 #include <boost/ref.hpp>
12 #include <boost/utility.hpp>
13 
14 #define BOOST_ENABLE_ASSERT_HANDLER
15 #include <boost/assert.hpp>
16 
17 using namespace boost::python;
18 
19 struct X
20 {
XX21     explicit X(int x) : x(x), magic(7654321) { ++counter; }
XX22     X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
~XX23     virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
24 
setX25     void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
valueX26     int value() const { BOOST_ASSERT(magic == 7654321); return x; }
countX27     static int count() { return counter; }
28  private:
29     void operator=(X const&);
30  private:
31     int x;
32     long magic;
33     static int counter;
34 };
35 
36 struct Y : X
37 {
YY38     Y(int x) : X(x) {};
39 };
40 
41 struct abstract : X
42 {
abstractabstract43     abstract(int x) : X(x) {};
call_fabstract44     int call_f(Y const& y) { return f(y); }
45     virtual int f(Y const& y) = 0;
call_gabstract46     abstract& call_g(Y const& y) { return g(y); }
47     virtual abstract& g(Y const& y) = 0;
48 };
49 
50 struct concrete : X
51 {
concreteconcrete52     concrete(int x) : X(x) {};
call_fconcrete53     int call_f(Y const& y) { return f(y); }
fconcrete54     virtual int f(Y const& y) { set(y.value()); return y.value(); }
55 };
56 
57 struct abstract_callback : abstract
58 {
abstract_callbackabstract_callback59     abstract_callback(PyObject* p, int x)
60         : abstract(x), self(p)
61     {}
62 
fabstract_callback63     int f(Y const& y)
64     {
65         return call_method<int>(self, "f", boost::ref(y));
66     }
67 
gabstract_callback68     abstract& g(Y const& y)
69     {
70         return call_method<abstract&>(self, "g", boost::ref(y));
71     }
72 
73     PyObject* self;
74 };
75 
76 struct concrete_callback : concrete
77 {
concrete_callbackconcrete_callback78     concrete_callback(PyObject* p, int x)
79         : concrete(x), self(p)
80     {}
81 
concrete_callbackconcrete_callback82     concrete_callback(PyObject* p, concrete const& x)
83         : concrete(x), self(p)
84     {}
85 
fconcrete_callback86     int f(Y const& y)
87     {
88         return call_method<int>(self, "f", boost::ref(y));
89     }
90 
f_implconcrete_callback91     int f_impl(Y const& y)
92     {
93         return this->concrete::f(y);
94     }
95 
96     PyObject* self;
97 };
98 
99 int X::counter;
100 
BOOST_PYTHON_MODULE(virtual_functions_ext)101 BOOST_PYTHON_MODULE(virtual_functions_ext)
102 {
103     class_<concrete, concrete_callback>("concrete", init<int>())
104         .def("value", &concrete::value)
105         .def("set", &concrete::set)
106         .def("call_f", &concrete::call_f)
107         .def("f", &concrete_callback::f_impl)
108         ;
109 
110     class_<abstract, boost::noncopyable, abstract_callback
111         >("abstract", init<int>())
112 
113         .def("value", &abstract::value)
114         .def("call_f", &abstract::call_f)
115         .def("call_g", &abstract::call_g, return_internal_reference<>())
116         .def("set", &abstract::set)
117         ;
118 
119     class_<Y>("Y", init<int>())
120         .def("value", &Y::value)
121         .def("set", &Y::set)
122         ;
123 }
124 
125 #include "module_tail.cpp"
126