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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
51
test/ben_scott1.cpp
Normal 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
14
test/ben_scott1.py
Normal 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()
|
||||
Reference in New Issue
Block a user