mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 17:52:17 +00:00
Tests and fixes for a bad interaction between wrapper<> and operators
support. "self" arguments weren't getting unwrapped properly. [SVN r35365]
This commit is contained in:
@@ -6,42 +6,28 @@
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/python/detail/is_wrapper.hpp>
|
||||
# if defined(BOOST_PYTHON_NO_SFINAE)
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# else
|
||||
# include <boost/python/detail/enable_if.hpp>
|
||||
# endif
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# if defined(BOOST_PYTHON_NO_SFINAE)
|
||||
template <class T>
|
||||
struct unwrap_wrapper_helper
|
||||
{
|
||||
typedef typename T::_wrapper_wrapped_type_ type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
typename mpl::eval_if<is_wrapper<T>,unwrap_wrapper_helper<T>,mpl::identity<T> >::type*
|
||||
unwrap_wrapper(T*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
template <class T>
|
||||
typename disable_if_ret<is_wrapper<T>,T*>::type
|
||||
unwrap_wrapper(T*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* unwrap_wrapper(wrapper<T>*)
|
||||
struct unwrap_wrapper_
|
||||
: mpl::eval_if<is_wrapper<T>,unwrap_wrapper_helper<T>,mpl::identity<T> >
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
typename unwrap_wrapper_<T>::type*
|
||||
unwrap_wrapper(T*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
|
||||
@@ -169,7 +169,9 @@ namespace detail \
|
||||
template <class L, class R> \
|
||||
struct apply \
|
||||
{ \
|
||||
static inline PyObject* execute(L& l, R const& r) \
|
||||
typedef typename unwrap_wrapper_<L>::type lhs; \
|
||||
typedef typename unwrap_wrapper_<R>::type rhs; \
|
||||
static PyObject* execute(lhs& l, rhs const& r) \
|
||||
{ \
|
||||
return detail::convert_result(expr); \
|
||||
} \
|
||||
@@ -183,7 +185,9 @@ namespace detail \
|
||||
template <class L, class R> \
|
||||
struct apply \
|
||||
{ \
|
||||
static inline PyObject* execute(R& r, L const& l) \
|
||||
typedef typename unwrap_wrapper_<L>::type lhs; \
|
||||
typedef typename unwrap_wrapper_<R>::type rhs; \
|
||||
static PyObject* execute(rhs& r, lhs const& l) \
|
||||
{ \
|
||||
return detail::convert_result(expr); \
|
||||
} \
|
||||
@@ -271,8 +275,10 @@ namespace detail \
|
||||
template <class L, class R> \
|
||||
struct apply \
|
||||
{ \
|
||||
static inline PyObject* \
|
||||
execute(back_reference<L&> l, R const& r) \
|
||||
typedef typename unwrap_wrapper_<L>::type lhs; \
|
||||
typedef typename unwrap_wrapper_<R>::type rhs; \
|
||||
static PyObject* \
|
||||
execute(back_reference<lhs&> l, rhs const& r) \
|
||||
{ \
|
||||
l.get() op r; \
|
||||
return python::incref(l.source().ptr()); \
|
||||
@@ -311,7 +317,8 @@ namespace detail \
|
||||
template <class T> \
|
||||
struct apply \
|
||||
{ \
|
||||
static PyObject* execute(T& x) \
|
||||
typedef typename unwrap_wrapper_<T>::type self_t; \
|
||||
static PyObject* execute(self_t& x) \
|
||||
{ \
|
||||
return detail::convert_result(op(x)); \
|
||||
} \
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace boost { namespace python {
|
||||
template <class T>
|
||||
class wrapper : public detail::wrapper_base
|
||||
{
|
||||
# if defined(BOOST_PYTHON_NO_SFINAE)
|
||||
public:
|
||||
// Do not touch this implementation detail!
|
||||
typedef T _wrapper_wrapped_type_;
|
||||
# endif
|
||||
|
||||
protected:
|
||||
override get_override(char const* name) const
|
||||
{
|
||||
|
||||
@@ -82,6 +82,7 @@ bpl-test crossmod_exception
|
||||
|
||||
[ bpl-test test_pointer_adoption ]
|
||||
[ bpl-test operators ]
|
||||
[ bpl-test operators_wrapper ]
|
||||
[ bpl-test callbacks ]
|
||||
[ bpl-test defaults ]
|
||||
|
||||
|
||||
42
test/operators_wrapper.cpp
Normal file
42
test/operators_wrapper.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "boost/python.hpp"
|
||||
#include <memory>
|
||||
|
||||
struct vector
|
||||
{
|
||||
virtual ~vector() {}
|
||||
|
||||
vector operator+( const vector& x ) const
|
||||
{ return vector(); }
|
||||
|
||||
vector& operator+=( const vector& x )
|
||||
{ return *this; }
|
||||
|
||||
vector operator-() const
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
struct dvector : vector
|
||||
{};
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct vector_wrapper
|
||||
: vector, wrapper< vector >
|
||||
{
|
||||
vector_wrapper(vector const&) {}
|
||||
vector_wrapper() {}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE( operators_wrapper_ext )
|
||||
{
|
||||
class_< vector_wrapper >( "vector" )
|
||||
.def( self + self )
|
||||
.def( self += self )
|
||||
.def( -self )
|
||||
;
|
||||
|
||||
scope().attr("v") = vector();
|
||||
std::auto_ptr<vector> dp(new dvector);
|
||||
register_ptr_to_python< std::auto_ptr<vector> >();
|
||||
scope().attr("d") = dp;
|
||||
}
|
||||
11
test/operators_wrapper.py
Normal file
11
test/operators_wrapper.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from operators_wrapper_ext import *
|
||||
|
||||
class D2(vector): pass
|
||||
d2 = D2()
|
||||
|
||||
for lhs in (v,d,d2):
|
||||
-lhs
|
||||
for rhs in (v,d,d2):
|
||||
lhs + rhs
|
||||
lhs += rhs
|
||||
|
||||
Reference in New Issue
Block a user