Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2001-05-14 20:55:51


Nick,

If the python 2.1 documentation (or even the release notes) gave even the
slightest hint about how to support these comparisons for extension types, I
might be able to help. Since I don't have time to pore through the Python
2.1 source code right now trying to find out whether these functions are
actually supported for types other than instances, I'm afraid you're on your
own in that department... but I'd say that's the place to start: find the
implementations of PyObjectCmp and PyObjectCompare
(http://www.python.org/doc/2.1/api/object.html#l2h-159).

Good luck,
Dave

----- Original Message -----
From: <nksauter_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Saturday, May 12, 2001 12:40 AM
Subject: [boost] Boost.Python support for Py 2.1 rich comparisons

> Now that Python 2.1 supports the notion of rich comparisons I
> would like to implement support for these operators in the
> Boost.Python library. My first attempt at doing this succeeded
> only partially: I was able to define the Python 2.1 customization
> functions (__gt__, __ge__, __lt__, __le__, __eq__, __ne__)
> but this did not produce the expected result of overloading the
> operators themselves, that is, a<b, etc. I am attaching the
> relevant code in the hope that someone will be able to understand
> what is missing.
>
> Nick Sauter
> Lawrence Berkeley Labs
>
> To reproduce my test:
>
> 1. Make differences to boost/python/detail/extension_class.hpp:
> 619,624d618
> < choose_op<(which & op_gt)>::template
> args<Operand>::add(this);
> < choose_op<(which & op_ge)>::template
> args<Operand>::add(this);
> < choose_op<(which & op_lt)>::template
> args<Operand>::add(this);
> < choose_op<(which & op_le)>::template
> args<Operand>::add(this);
> < choose_op<(which & op_eq)>::template
> args<Operand>::add(this);
> < choose_op<(which & op_ne)>::template
> args<Operand>::add(this);
> 654,659d647
> < choose_op<(which & op_gt)>::template
> args<Left,Right>::add(this);
> < choose_op<(which & op_ge)>::template
> args<Left,Right>::add(this);
> < choose_op<(which & op_lt)>::template
> args<Left,Right>::add(this);
> < choose_op<(which & op_le)>::template
> args<Left,Right>::add(this);
> < choose_op<(which & op_eq)>::template
> args<Left,Right>::add(this);
> < choose_op<(which & op_ne)>::template
> args<Left,Right>::add(this);
>
> 2. Make differences to boost/python/operators.hpp:
> 68,74c68
> < op_cmp = 0x100000,
> < op_gt = 0x200000,
> < op_ge = 0x400000,
> < op_lt = 0x800000,
> < op_le = 0x1000000,
> < op_eq = 0x2000000,
> < op_ne = 0x4000000
> ---
> > op_cmp = 0x100000
> 310,315d303
> < PY_DEFINE_BINARY_OPERATORS(gt, >);
> < PY_DEFINE_BINARY_OPERATORS(ge, >=);
> < PY_DEFINE_BINARY_OPERATORS(lt, <);
> < PY_DEFINE_BINARY_OPERATORS(le, <=);
> < PY_DEFINE_BINARY_OPERATORS(eq, ==);
> < PY_DEFINE_BINARY_OPERATORS(ne, !=);
>
> 3. Now compile the following extension module, richcmpmodule.cpp:
> #include <boost/python/cross_module.hpp>
> #include <libs/python/example/dvect.h>
>
> namespace {
> #include <cctbx/basic/from_bpl_import.h>
> #include <libs/python/example/dvect_conversions.cpp>
> }//namespace
>
> #define DVECT_BINARY_OPERATORS( oper ) \
> vects::dvect operator##oper (const vects::dvect& a, const
> vects::dvect& b) {\
> if (a.size()!=b.size()){throw boost::python::argument_error();}
> \
> vects::dvect result(a.size());
> \
> vects::dvect::const_iterator a_it = a.begin();
> \
> vects::dvect::const_iterator b_it = b.begin();
> \
> vects::dvect::iterator r_it = result.begin();
> \
> for (int i=0; i<a.size(); i++) { r_it[i] = (a_it[i] ##oper
> b_it[i]);
> } \
> return result;
> \
> }
> DVECT_BINARY_OPERATORS( + )
> DVECT_BINARY_OPERATORS( - )
> DVECT_BINARY_OPERATORS( * )
> DVECT_BINARY_OPERATORS( / )
> DVECT_BINARY_OPERATORS( > )
> DVECT_BINARY_OPERATORS( >= )
> DVECT_BINARY_OPERATORS( < )
> DVECT_BINARY_OPERATORS( <= )
> DVECT_BINARY_OPERATORS( == )
> DVECT_BINARY_OPERATORS( != )
> #undef DVECT_BINARY_OPERATORS
>
> BOOST_PYTHON_MODULE_INIT(richcmp)
> {
> try
> {
> python::module_builder richcmp_module("richcmp");
> python::class_builder<vects::dvect> dvect_class(richcmp_module,
> "dvect");
> dvect_class.def(python::constructor<python::tuple>());
> dvect_class.def(&vects::dvect::as_tuple,"as_tuple");
>
> #define all_operators (boost::python::op_mul | boost::python::op_add
> |
> boost::python::op_div | boost::python::op_sub )
> dvect_class.def(boost::python::operators<all_operators>());
>
> #define comp_operators (boost::python::op_gt | boost::python::op_ge
> |\
> boost::python::op_lt | boost::python::op_le | \
> boost::python::op_eq | boost::python::op_ne)
> dvect_class.def(boost::python::operators<comp_operators>());
> }
> catch(...){python::handle_exception();}//Deal with the exception
> for
> Python
> }
>
> 4. Test the module:
> import richcmp
> dv = richcmp.dvect((1,2,3,4,5))
> print dv.as_tuple()
> dv2 = richcmp.dvect((6,7,8,9,10))
> print dv2.as_tuple()
>
> print (dv+dv2).as_tuple()
>
> print dv.__eq__(dv2).as_tuple()
> print dv.__ne__(dv2).as_tuple()
>
> print (dv == dv2) #result should be a dvect but comes out as an int
>
>
> To unsubscribe, send email to: <mailto:boost-unsubscribe_at_[hidden]>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk