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)
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>
14 #define BOOST_ENABLE_ASSERT_HANDLER
15 #include <boost/assert.hpp>
17 using namespace boost::python
;
21 explicit X(int x
) : x(x
), magic(7654321) { ++counter
; }
22 X(X
const& rhs
) : x(rhs
.x
), magic(7654321) { ++counter
; }
23 virtual ~X() { BOOST_ASSERT(magic
== 7654321); magic
= 6666666; x
= 9999; --counter
; }
25 void set(int _x
) { BOOST_ASSERT(magic
== 7654321); this->x
= _x
; }
26 int value() const { BOOST_ASSERT(magic
== 7654321); return x
; }
27 static int count() { return counter
; }
29 void operator=(X
const&);
43 abstract(int x
) : X(x
) {};
44 int call_f(Y
const& y
) { return f(y
); }
45 virtual int f(Y
const& y
) = 0;
46 abstract
& call_g(Y
const& y
) { return g(y
); }
47 virtual abstract
& g(Y
const& y
) = 0;
52 concrete(int x
) : X(x
) {};
53 int call_f(Y
const& y
) { return f(y
); }
54 virtual int f(Y
const& y
) { set(y
.value()); return y
.value(); }
57 struct abstract_callback
: abstract
59 abstract_callback(PyObject
* p
, int x
)
60 : abstract(x
), self(p
)
65 return call_method
<int>(self
, "f", boost::ref(y
));
68 abstract
& g(Y
const& y
)
70 return call_method
<abstract
&>(self
, "g", boost::ref(y
));
76 struct concrete_callback
: concrete
78 concrete_callback(PyObject
* p
, int x
)
79 : concrete(x
), self(p
)
82 concrete_callback(PyObject
* p
, concrete
const& x
)
83 : concrete(x
), self(p
)
88 return call_method
<int>(self
, "f", boost::ref(y
));
91 int f_impl(Y
const& y
)
93 return this->concrete::f(y
);
101 BOOST_PYTHON_MODULE(virtual_functions_ext
)
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
)
110 class_
<abstract
, boost::noncopyable
, abstract_callback
111 >("abstract", init
<int>())
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
)
119 class_
<Y
>("Y", init
<int>())
120 .def("value", &Y::value
)
125 #include "module_tail.cpp"