From 92aae63af2995dd0f0cd16a44b461ddec4ca96e5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 18:35:09 +0000 Subject: [PATCH] str(), pow(), complex() support [SVN r14070] --- include/boost/python/detail/operator_id.hpp | 3 +- include/boost/python/operators2.hpp | 57 +++++++++++++++++++-- src/object/function.cpp | 10 +++- test/operators.cpp | 35 +++++++++++++ test/operators.py | 11 ++++ 5 files changed, 110 insertions(+), 6 deletions(-) diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp index 9005c7ae..0c28b2d4 100755 --- a/include/boost/python/detail/operator_id.hpp +++ b/include/boost/python/detail/operator_id.hpp @@ -46,7 +46,8 @@ enum operator_id op_irshift, op_iand, op_ixor, - op_ior + op_ior, + op_complex, }; }}} // namespace boost::python::detail diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index c4365b35..36d5e16b 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -13,6 +13,9 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { @@ -132,7 +135,7 @@ namespace detail }; } -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ namespace detail \ { \ template <> \ @@ -143,7 +146,7 @@ namespace detail \ { \ static inline PyObject* execute(L const& l, R const& r) \ { \ - return detail::convert_result(l op r); \ + return detail::convert_result(expr); \ } \ }; \ static char const* name() { return "__" #id "__"; } \ @@ -157,12 +160,15 @@ namespace detail \ { \ static inline PyObject* execute(R const& r, L const& l) \ { \ - return detail::convert_result(l op r); \ + return detail::convert_result(expr); \ } \ }; \ static char const* name() { return "__" #rid "__"; } \ }; \ -} \ +} + +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ namespace self_ns \ { \ template \ @@ -190,6 +196,44 @@ BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) +// pow isn't an operator in C++; handle it specially. +BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) +namespace self_ns +{ +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + template + inline detail::operator_ + pow(L const&, R const&) + { + return detail::operator_(); + } +# else + // When there's no argument-dependent lookup, we need these + // overloads to handle the case when everything is imported into the + // global namespace. Note that the plain overload below does /not/ + // take const& arguments. This is needed by MSVC6 at least, or it + // complains of ambiguities, since there's no partial ordering. + inline detail::operator_ + pow(self_t, self_t) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(self_t const&, R const&) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(L const&, self_t const&) + { + return detail::operator_(); + } +# endif +} + + # define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ namespace detail \ { \ @@ -263,6 +307,8 @@ BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) +BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) +BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) }} // namespace boost::python @@ -271,6 +317,9 @@ using boost::python::self_ns::abs; using boost::python::self_ns::int_; using boost::python::self_ns::long_; using boost::python::self_ns::float_; +using boost::python::self_ns::complex_; +using boost::python::self_ns::str; +using boost::python::self_ns::pow; # endif #endif // OPERATORS2_DWA2002530_HPP diff --git a/src/object/function.cpp b/src/object/function.cpp index 021770b0..0d89791c 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -86,7 +86,9 @@ namespace "add__", "and__", "div__", + "divmod__", "eq__", + "floordiv__", "ge__", "gt__", "le__", @@ -96,19 +98,25 @@ namespace "mul__", "ne__", "or__", + "pow__", "radd__", "rand__", "rdiv__", + "rdivmod__", + "rfloordiv__", "rlshift__", "rmod__", "rmul__", "ror__", + "rpow__", "rrshift__", "rshift__", "rsub__", + "rtruediv__", "rxor__", "sub__", - "xor__", + "truediv__", + "xor__" }; struct less_cstring diff --git a/test/operators.cpp b/test/operators.cpp index 3a33990f..8a0c57d1 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -8,6 +8,15 @@ #include #include #include "test_class.hpp" +#if __GNUC__ != 2 +# include +#else +# include +#endif + +// Just use math.h here; trying to use std::pow() causes too much +// trouble for non-conforming compilers and libraries. +#include using namespace boost::python; @@ -27,6 +36,26 @@ bool operator<(int x, X const& y) { return x < y.value(); } X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } +X pow(X x, int y) +{ + return X(int(pow(double(x.value()), y))); +} + +X pow(X x, X y) +{ + return X(int(pow(double(x.value()), y.value()))); +} + +int pow(int x, X y) +{ + return int(pow(double(x), y.value())); +} + +std::ostream& operator<<(std::ostream& s, X const& x) +{ + return s << x.value(); +} + BOOST_PYTHON_MODULE_INIT(operators_ext) { module("operators_ext") @@ -43,12 +72,18 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(1 < self) .def(self -= self) .def(abs(self)) + .def(str(self)) + + .def(pow(self,self)) + .def(pow(self,int())) + .def(pow(int(),self)) ) .add( class_ >("Z") .def_init(args()) .def(int_(self)) .def(float_(self)) + .def(complex_(self)) ) ; } diff --git a/test/operators.py b/test/operators.py index 951ac806..58ffb5eb 100644 --- a/test/operators.py +++ b/test/operators.py @@ -53,12 +53,23 @@ >>> x -= y >>> x.value() 5 +>>> str(x) +'5' >>> z = Z(10) >>> int(z) 10 >>> float(z) 10.0 +>>> complex(z) +(10+0j) + +>>> pow(2,x) +32 +>>> pow(x,2).value() +25 +>>> pow(X(2),x).value() +32 ''' def run(args = None):