Skip to content

Commit 92aae63

Browse files
committed
str(), pow(), complex() support
[SVN r14070]
1 parent b042644 commit 92aae63

5 files changed

Lines changed: 110 additions & 6 deletions

File tree

include/boost/python/detail/operator_id.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ enum operator_id
4646
op_irshift,
4747
op_iand,
4848
op_ixor,
49-
op_ior
49+
op_ior,
50+
op_complex,
5051
};
5152

5253
}}} // namespace boost::python::detail

include/boost/python/operators2.hpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
# include <boost/mpl/select_type.hpp>
1414
# include <boost/python/self.hpp>
1515
# include <boost/python/other.hpp>
16+
# include <boost/lexical_cast.hpp>
17+
# include <string>
18+
# include <complex>
1619

1720
namespace boost { namespace python {
1821

@@ -132,7 +135,7 @@ namespace detail
132135
};
133136
}
134137

135-
# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
138+
# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
136139
namespace detail \
137140
{ \
138141
template <> \
@@ -143,7 +146,7 @@ namespace detail \
143146
{ \
144147
static inline PyObject* execute(L const& l, R const& r) \
145148
{ \
146-
return detail::convert_result(l op r); \
149+
return detail::convert_result(expr); \
147150
} \
148151
}; \
149152
static char const* name() { return "__" #id "__"; } \
@@ -157,12 +160,15 @@ namespace detail \
157160
{ \
158161
static inline PyObject* execute(R const& r, L const& l) \
159162
{ \
160-
return detail::convert_result(l op r); \
163+
return detail::convert_result(expr); \
161164
} \
162165
}; \
163166
static char const* name() { return "__" #rid "__"; } \
164167
}; \
165-
} \
168+
}
169+
170+
# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
171+
BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
166172
namespace self_ns \
167173
{ \
168174
template <class L, class R> \
@@ -190,6 +196,44 @@ BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
190196
BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
191197
BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
192198

199+
// pow isn't an operator in C++; handle it specially.
200+
BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
201+
namespace self_ns
202+
{
203+
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
204+
template <class L, class R>
205+
inline detail::operator_<detail::op_pow,L,R>
206+
pow(L const&, R const&)
207+
{
208+
return detail::operator_<detail::op_pow,L,R>();
209+
}
210+
# else
211+
// When there's no argument-dependent lookup, we need these
212+
// overloads to handle the case when everything is imported into the
213+
// global namespace. Note that the plain overload below does /not/
214+
// take const& arguments. This is needed by MSVC6 at least, or it
215+
// complains of ambiguities, since there's no partial ordering.
216+
inline detail::operator_<detail::op_pow,self_t,self_t>
217+
pow(self_t, self_t)
218+
{
219+
return detail::operator_<detail::op_pow,self_t,self_t>();
220+
}
221+
template <class R>
222+
inline detail::operator_<detail::op_pow,self_t,R>
223+
pow(self_t const&, R const&)
224+
{
225+
return detail::operator_<detail::op_pow,self_t,R>();
226+
}
227+
template <class L>
228+
inline detail::operator_<detail::op_pow,L,self_t>
229+
pow(L const&, self_t const&)
230+
{
231+
return detail::operator_<detail::op_pow,L,self_t>();
232+
}
233+
# endif
234+
}
235+
236+
193237
# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
194238
namespace detail \
195239
{ \
@@ -263,6 +307,8 @@ BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
263307
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
264308
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
265309
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
310+
BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
311+
BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
266312

267313
}} // namespace boost::python
268314

@@ -271,6 +317,9 @@ using boost::python::self_ns::abs;
271317
using boost::python::self_ns::int_;
272318
using boost::python::self_ns::long_;
273319
using boost::python::self_ns::float_;
320+
using boost::python::self_ns::complex_;
321+
using boost::python::self_ns::str;
322+
using boost::python::self_ns::pow;
274323
# endif
275324

276325
#endif // OPERATORS2_DWA2002530_HPP

src/object/function.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ namespace
8686
"add__",
8787
"and__",
8888
"div__",
89+
"divmod__",
8990
"eq__",
91+
"floordiv__",
9092
"ge__",
9193
"gt__",
9294
"le__",
@@ -96,19 +98,25 @@ namespace
9698
"mul__",
9799
"ne__",
98100
"or__",
101+
"pow__",
99102
"radd__",
100103
"rand__",
101104
"rdiv__",
105+
"rdivmod__",
106+
"rfloordiv__",
102107
"rlshift__",
103108
"rmod__",
104109
"rmul__",
105110
"ror__",
111+
"rpow__",
106112
"rrshift__",
107113
"rshift__",
108114
"rsub__",
115+
"rtruediv__",
109116
"rxor__",
110117
"sub__",
111-
"xor__",
118+
"truediv__",
119+
"xor__"
112120
};
113121

114122
struct less_cstring

test/operators.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
#include <boost/python/class.hpp>
99
#include <boost/python/module.hpp>
1010
#include "test_class.hpp"
11+
#if __GNUC__ != 2
12+
# include <ostream>
13+
#else
14+
# include <ostream.h>
15+
#endif
16+
17+
// Just use math.h here; trying to use std::pow() causes too much
18+
// trouble for non-conforming compilers and libraries.
19+
#include <math.h>
1120

1221
using namespace boost::python;
1322

@@ -27,6 +36,26 @@ bool operator<(int x, X const& y) { return x < y.value(); }
2736

2837
X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); }
2938

39+
X pow(X x, int y)
40+
{
41+
return X(int(pow(double(x.value()), y)));
42+
}
43+
44+
X pow(X x, X y)
45+
{
46+
return X(int(pow(double(x.value()), y.value())));
47+
}
48+
49+
int pow(int x, X y)
50+
{
51+
return int(pow(double(x), y.value()));
52+
}
53+
54+
std::ostream& operator<<(std::ostream& s, X const& x)
55+
{
56+
return s << x.value();
57+
}
58+
3059
BOOST_PYTHON_MODULE_INIT(operators_ext)
3160
{
3261
module("operators_ext")
@@ -43,12 +72,18 @@ BOOST_PYTHON_MODULE_INIT(operators_ext)
4372
.def(1 < self)
4473
.def(self -= self)
4574
.def(abs(self))
75+
.def(str(self))
76+
77+
.def(pow(self,self))
78+
.def(pow(self,int()))
79+
.def(pow(int(),self))
4680
)
4781
.add(
4882
class_<test_class<1> >("Z")
4983
.def_init(args<int>())
5084
.def(int_(self))
5185
.def(float_(self))
86+
.def(complex_(self))
5287
)
5388
;
5489
}

test/operators.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,23 @@
5353
>>> x -= y
5454
>>> x.value()
5555
5
56+
>>> str(x)
57+
'5'
5658
5759
>>> z = Z(10)
5860
>>> int(z)
5961
10
6062
>>> float(z)
6163
10.0
64+
>>> complex(z)
65+
(10+0j)
66+
67+
>>> pow(2,x)
68+
32
69+
>>> pow(x,2).value()
70+
25
71+
>>> pow(X(2),x).value()
72+
32
6273
'''
6374

6475
def run(args = None):

0 commit comments

Comments
 (0)