|
Boost : |
From: nksauter_at_[hidden]
Date: 2001-05-11 23:40:35
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk