2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 05:02:17 +00:00

bug fix + regression test

[SVN r17002]
This commit is contained in:
Dave Abrahams
2003-01-23 04:32:10 +00:00
parent 399cf70b92
commit 9dfe98abb0
5 changed files with 74 additions and 10 deletions

View File

@@ -40,13 +40,7 @@ namespace detail
template <class T>
struct return_rvalue_from_python
{
typedef typename mpl::if_<
mpl::logical_and<
has_trivial_copy<T>, mpl::bool_c<(sizeof(T) <= 2 * sizeof(double))>
>
, T
, T&
>::type result_type;
typedef T result_type;
return_rvalue_from_python();
result_type operator()(PyObject*);
@@ -127,6 +121,12 @@ namespace detail
inline typename return_rvalue_from_python<T>::result_type
return_rvalue_from_python<T>::operator()(PyObject* obj)
{
// Take possession of the source object here. If the result is in
// fact going to be a copy of an lvalue embedded in the object,
// and we take possession inside rvalue_result_from_python, it
// will be destroyed too early.
handle<> holder(obj);
return *(T*)
(rvalue_result_from_python)(obj, m_data.stage1);
}

View File

@@ -83,9 +83,6 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
BOOST_PYTHON_DECL void* rvalue_result_from_python(
PyObject* src, rvalue_from_python_stage1_data& data)
{
// Take possession of the source object.
handle<> holder(src);
// Retrieve the registration
// Cast in two steps for less-capable compilers
void const* converters_ = data.convertible;

View File

@@ -95,6 +95,8 @@ bpl-test back_reference ;
bpl-test implicit ;
bpl-test data_members ;
bpl-test ben_scott1 ;
bpl-test bienstman1 ;
bpl-test bienstman2 ;
bpl-test bienstman3 ;

51
test/ben_scott1.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
using namespace boost;
struct Product {};
typedef shared_ptr<Product> ProductPtr;
struct Creator
{
virtual ~Creator() {}
virtual ProductPtr create() = 0;
};
struct Factory
{
void reg(Creator* c) { mC = c; }
ProductPtr create()
{
std::cout << "Name: " << (typeid(*mC)).name() << std::endl;
return mC->create();
}
private:
Creator* mC;
};
struct CreatorWrap : public Creator
{
CreatorWrap(PyObject* self) : mSelf(self) {}
ProductPtr create() { return call_method<ProductPtr>(mSelf, "create"); }
PyObject* mSelf;
};
BOOST_PYTHON_MODULE(ben_scott1_ext)
{
class_<Product, ProductPtr>("Product");
class_<Creator, CreatorWrap, noncopyable>("Creator")
.def("create", &CreatorWrap::create)
;
class_<Factory>("Factory")
.def("reg", &Factory::reg, with_custodian_and_ward<1,2>())
.def("create", &Factory::create)
;
}
#include "../test/module_tail.cpp"

14
test/ben_scott1.py Normal file
View File

@@ -0,0 +1,14 @@
# This regression test checks that call_method<T>(...) where T is a
# non-reference, non-pointer type that happens to be held inside the
# result object (and thus is found as an lvalue) works.
from ben_scott1_ext import *
class CreatorImpl(Creator):
def create(self):
return Product()
factory = Factory()
c = CreatorImpl()
factory.reg(c)
a = factory.create()