2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-28 07:22:31 +00:00

Enable automatic downcasting to registered classes for pointers, references, and smart pointers

[SVN r16673]
This commit is contained in:
Dave Abrahams
2002-12-20 18:19:18 +00:00
parent 3d874d1618
commit 0c8aa84f2f
9 changed files with 188 additions and 41 deletions

View File

@@ -3,7 +3,14 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/def.hpp>
#include <boost/utility.hpp>
using namespace boost::python;
@@ -40,6 +47,11 @@ struct B : A
virtual std::string f() { return "B::f()"; }
};
struct C : A
{
virtual std::string f() { return "C::f()"; }
};
A& getBCppObj ()
{
static B b;
@@ -48,6 +60,25 @@ A& getBCppObj ()
std::string call_f(A& a) { return a.f(); }
A* factory(unsigned choice)
{
switch (choice % 3)
{
case 0: return new A;
break;
case 1: return new B;
break;
default: return new C;
break;
}
}
C& getCCppObj ()
{
static C c;
return c;
}
BOOST_PYTHON_MODULE_INIT(polymorphism_ext)
{
class_<A,boost::noncopyable,ACallback>("A")
@@ -56,6 +87,14 @@ BOOST_PYTHON_MODULE_INIT(polymorphism_ext)
def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
class_<C,bases<A>,boost::noncopyable>("C")
.def("f", &C::f)
;
def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
def("factory", factory, return_value_policy<manage_new_object>());
def("call_f", call_f);
}

View File

@@ -17,17 +17,31 @@ class PolymorphTest(unittest.TestCase):
self.failUnlessEqual ('B::f()', a.f())
self.failUnlessEqual ('B::f()', call_f(a))
self.failUnlessEqual ('A::f()', call_f(A()))
def test_references(self):
# B is not exposed to Python
a = getBCppObj()
self.failUnlessEqual(type(a), A)
# C is exposed to Python
c = getCCppObj()
self.failUnlessEqual(type(c), C)
def test_factory(self):
self.failUnlessEqual(type(factory(0)), A)
self.failUnlessEqual(type(factory(1)), A)
self.failUnlessEqual(type(factory(2)), C)
def testReturnPy(self):
class C(A):
class D(A):
def f(self):
return 'C.f'
return 'D.f'
c = C()
d = D()
self.failUnlessEqual ('C.f', c.f())
self.failUnlessEqual ('C.f', call_f(c))
self.failUnlessEqual ('D.f', d.f())
self.failUnlessEqual ('D.f', call_f(d))
if __name__ == "__main__":

View File

@@ -82,6 +82,16 @@ struct ZWrap : Z
PyObject* m_self;
};
struct YY : Y
{
YY(int n) : Y(n) {}
};
shared_ptr<Y> factory(int n)
{
return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
}
static int stored_v() { return functions<Z>::get()->v(); }
BOOST_PYTHON_MODULE(shared_ptr_ext)
@@ -90,6 +100,8 @@ BOOST_PYTHON_MODULE(shared_ptr_ext)
.def("value", &X::value)
;
def("factory", factory);
functions<X>::expose();
def("x_count", &X::count);
def("x_release", &functions<X>::release_store);
@@ -99,6 +111,9 @@ BOOST_PYTHON_MODULE(shared_ptr_ext)
.def("value", &Y::value)
;
class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
;
functions<Y>::expose();
def("y_count", &Y::count);
def("y_release", &functions<Y>::release_store);

View File

@@ -1,5 +1,11 @@
'''
>>> from shared_ptr_ext import *
>>> type(factory(3))
<class 'shared_ptr_ext.Y'>
>>> type(factory(42))
<class 'shared_ptr_ext.YY'>
>>> class P(Z):
... def v(self):
... return -Z.v(self);