// Example by Nicholas K. Sauter & Ralf W. Grosse-Kunstleve. // Comprehensive operator overloading for two vector types and scalars. #include "dvect.h" #include "ivect.h" #include //------------------ Overload DVECT -------------------------------- #define DVECT_BINARY_OPERATORS( oper ) \ namespace vects { \ dvect operator##oper (const dvect& a, const dvect& b) { \ if (a.size()!=b.size()){throw boost::python::argument_error();} \ dvect result(a.size()); \ dvect::const_iterator a_it = a.begin(); \ dvect::const_iterator b_it = b.begin(); \ dvect::iterator r_it = result.begin(); \ for (int i=0; i ) DVECT_BINARY_OPERATORS( >= ) DVECT_BINARY_OPERATORS( < ) DVECT_BINARY_OPERATORS( <= ) DVECT_BINARY_OPERATORS( == ) DVECT_BINARY_OPERATORS( != ) #undef DVECT_BINARY_OPERATORS #define DVECT_SCALAR_BINARY_OPERATORS( scalar_type, oper ) \ namespace vects { \ dvect operator##oper (const dvect& a, const scalar_type& b) { \ dvect result(a.size()); \ dvect::const_iterator a_it = a.begin(); \ dvect::iterator r_it = result.begin(); \ for (int i=0; i ) DVECT_SCALAR_BINARY_OPERATORS( double, >= ) DVECT_SCALAR_BINARY_OPERATORS( double, < ) DVECT_SCALAR_BINARY_OPERATORS( double, <= ) DVECT_SCALAR_BINARY_OPERATORS( double, == ) DVECT_SCALAR_BINARY_OPERATORS( double, != ) #undef DVECT_SCALAR_BINARY_OPERATORS #define SCALAR_DVECT_BINARY_OPERATORS( scalar_type, oper ) \ namespace vects { \ dvect operator##oper (const scalar_type& a, const dvect& b) { \ dvect result(b.size()); \ dvect::const_iterator b_it = b.begin(); \ dvect::iterator r_it = result.begin(); \ for (int i=0; i ) IVECT_BINARY_OPERATORS( >= ) IVECT_BINARY_OPERATORS( < ) IVECT_BINARY_OPERATORS( <= ) IVECT_BINARY_OPERATORS( == ) IVECT_BINARY_OPERATORS( != ) #undef IVECT_BINARY_OPERATORS #define IVECT_SCALAR_BINARY_OPERATORS( scalar_type, oper ) \ namespace vects { \ ivect operator##oper (const ivect& a, const scalar_type& b) { \ ivect result(a.size()); \ ivect::const_iterator a_it = a.begin(); \ ivect::iterator r_it = result.begin(); \ for (int i=0; i ) IVECT_SCALAR_BINARY_OPERATORS( int, >= ) IVECT_SCALAR_BINARY_OPERATORS( int, < ) IVECT_SCALAR_BINARY_OPERATORS( int, <= ) IVECT_SCALAR_BINARY_OPERATORS( int, == ) IVECT_SCALAR_BINARY_OPERATORS( int, != ) #undef IVECT_SCALAR_BINARY_OPERATORS #define SCALAR_IVECT_BINARY_OPERATORS( scalar_type, oper ) \ namespace vects { \ ivect operator##oper (const scalar_type& a, const ivect& b) { \ ivect result(b.size()); \ ivect::const_iterator b_it = b.begin(); \ ivect::iterator r_it = result.begin(); \ for (int i=0; i ) DI_BINARY_OPERATORS( >= ) DI_BINARY_OPERATORS( < ) DI_BINARY_OPERATORS( <= ) DI_BINARY_OPERATORS( == ) DI_BINARY_OPERATORS( != ) #undef DI_BINARY_OPERATORS #define ID_BINARY_OPERATORS( oper ) \ namespace vects { \ dvect operator##oper (const ivect& a, const dvect& b) { \ if (a.size()!=b.size()){throw boost::python::argument_error();} \ dvect result(a.size()); \ ivect::const_iterator a_it = a.begin(); \ dvect::const_iterator b_it = b.begin(); \ dvect::iterator r_it = result.begin(); \ for (int i=0; i ) ID_BINARY_OPERATORS( >= ) ID_BINARY_OPERATORS( < ) ID_BINARY_OPERATORS( <= ) ID_BINARY_OPERATORS( == ) ID_BINARY_OPERATORS( != ) #undef ID_BINARY_OPERATORS //-------------------- Module --------------------------------------- #define all_operators (boost::python::op_mul | boost::python::op_add |\ boost::python::op_div | boost::python::op_sub ) #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) namespace { void init_module(boost::python::module_builder& this_module) { boost::python::class_builder dvect_class(this_module, "dvect"); boost::python::class_builder ivect_class(this_module, "ivect"); dvect_class.def(boost::python::constructor()); dvect_class.def(&vects::dvect::as_tuple,"as_tuple"); dvect_class.def(boost::python::operators()); dvect_class.def(boost::python::operators(), boost::python::right_operand() ); dvect_class.def(boost::python::operators(), boost::python::left_operand() ); dvect_class.def(boost::python::operators(), boost::python::right_operand() ); dvect_class.def(boost::python::operators()); dvect_class.def(boost::python::operators(), boost::python::right_operand() ); // left_operand not needed since Python uses reflection dvect_class.def(boost::python::operators(), boost::python::right_operand() ); ivect_class.def(boost::python::constructor()); ivect_class.def(&vects::ivect::as_tuple,"as_tuple"); ivect_class.def(boost::python::operators()); ivect_class.def(boost::python::operators(), boost::python::right_operand() ); ivect_class.def(boost::python::operators(), boost::python::left_operand() ); ivect_class.def(boost::python::operators(), boost::python::right_operand() ); ivect_class.def(boost::python::operators()); ivect_class.def(boost::python::operators(), boost::python::right_operand() ); // left_operand not needed since Python uses reflection ivect_class.def(boost::python::operators(), boost::python::right_operand() ); } } // namespace BOOST_PYTHON_MODULE_INIT(richcmp3) { try { boost::python::module_builder this_module("richcmp3"); // The actual work is done in a separate function in order // to suppress a bogus VC60 warning. init_module(this_module); } catch(...){boost::python::handle_exception();} }