From 94500ae36debfe45eb0a47b53c81fd0fa530661a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Sep 2006 14:41:01 +0000 Subject: [PATCH] Tests and fixes for a bad interaction between wrapper<> and operators support. "self" arguments weren't getting unwrapped properly. [SVN r35365] --- .../boost/python/detail/unwrap_wrapper.hpp | 32 ++++---------- include/boost/python/operators.hpp | 17 +++++--- include/boost/python/wrapper.hpp | 4 +- test/Jamfile.v2 | 1 + test/operators_wrapper.cpp | 42 +++++++++++++++++++ test/operators_wrapper.py | 11 +++++ 6 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 test/operators_wrapper.cpp create mode 100644 test/operators_wrapper.py diff --git a/include/boost/python/detail/unwrap_wrapper.hpp b/include/boost/python/detail/unwrap_wrapper.hpp index a0f6a65a..95bc233a 100755 --- a/include/boost/python/detail/unwrap_wrapper.hpp +++ b/include/boost/python/detail/unwrap_wrapper.hpp @@ -6,42 +6,28 @@ # include # include -# if defined(BOOST_PYTHON_NO_SFINAE) -# include -# include -# else -# include -# endif +# include +# include namespace boost { namespace python { namespace detail { -# if defined(BOOST_PYTHON_NO_SFINAE) template struct unwrap_wrapper_helper { typedef typename T::_wrapper_wrapped_type_ type; }; - -template -typename mpl::eval_if,unwrap_wrapper_helper,mpl::identity >::type* -unwrap_wrapper(T*) -{ - return 0; -} -# else -template -typename disable_if_ret,T*>::type -unwrap_wrapper(T*) -{ - return 0; -} template -T* unwrap_wrapper(wrapper*) +struct unwrap_wrapper_ + : mpl::eval_if,unwrap_wrapper_helper,mpl::identity > +{}; + +template +typename unwrap_wrapper_::type* +unwrap_wrapper(T*) { return 0; } -# endif }}} // namespace boost::python::detail diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 89fe4099..3851b494 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -169,7 +169,9 @@ namespace detail \ template \ struct apply \ { \ - static inline PyObject* execute(L& l, R const& r) \ + typedef typename unwrap_wrapper_::type lhs; \ + typedef typename unwrap_wrapper_::type rhs; \ + static PyObject* execute(lhs& l, rhs const& r) \ { \ return detail::convert_result(expr); \ } \ @@ -183,7 +185,9 @@ namespace detail \ template \ struct apply \ { \ - static inline PyObject* execute(R& r, L const& l) \ + typedef typename unwrap_wrapper_::type lhs; \ + typedef typename unwrap_wrapper_::type rhs; \ + static PyObject* execute(rhs& r, lhs const& l) \ { \ return detail::convert_result(expr); \ } \ @@ -271,8 +275,10 @@ namespace detail \ template \ struct apply \ { \ - static inline PyObject* \ - execute(back_reference l, R const& r) \ + typedef typename unwrap_wrapper_::type lhs; \ + typedef typename unwrap_wrapper_::type rhs; \ + static PyObject* \ + execute(back_reference l, rhs const& r) \ { \ l.get() op r; \ return python::incref(l.source().ptr()); \ @@ -311,7 +317,8 @@ namespace detail \ template \ struct apply \ { \ - static PyObject* execute(T& x) \ + typedef typename unwrap_wrapper_::type self_t; \ + static PyObject* execute(self_t& x) \ { \ return detail::convert_result(op(x)); \ } \ diff --git a/include/boost/python/wrapper.hpp b/include/boost/python/wrapper.hpp index 28871a5e..166c8e23 100755 --- a/include/boost/python/wrapper.hpp +++ b/include/boost/python/wrapper.hpp @@ -14,10 +14,10 @@ namespace boost { namespace python { template 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 { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 78ac8d8d..81db0676 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -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 ] diff --git a/test/operators_wrapper.cpp b/test/operators_wrapper.cpp new file mode 100644 index 00000000..f00aa2b4 --- /dev/null +++ b/test/operators_wrapper.cpp @@ -0,0 +1,42 @@ +#include "boost/python.hpp" +#include + +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 dp(new dvector); + register_ptr_to_python< std::auto_ptr >(); + scope().attr("d") = dp; +} diff --git a/test/operators_wrapper.py b/test/operators_wrapper.py new file mode 100644 index 00000000..6c889b0a --- /dev/null +++ b/test/operators_wrapper.py @@ -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 +