From 4eff7ba8a9b0f836f73d6f49835183b09fb0de64 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 15 Nov 2000 05:58:53 +0000 Subject: [PATCH] Support a more minimal interface UPPERCASE_MACRO_NAMES [SVN r8213] --- operators.h | 653 +++++++++++++++++++++++++++++----------------------- 1 file changed, 364 insertions(+), 289 deletions(-) diff --git a/operators.h b/operators.h index 31fdd3aa..86df0d4f 100644 --- a/operators.h +++ b/operators.h @@ -2,343 +2,418 @@ #define OPERATORS_UK112000_H_ #include "functions.h" -#include +#if !defined(__GNUC__) || defined(__SGI_STL_PORT) +# include +#else +# include +#endif -namespace py -{ +namespace py { -namespace detail -{ +namespace detail { - template <> - struct define_operator<0> - { - template - struct operator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* keywords) const - { - PyErr_SetString(PyExc_TypeError, "operator not implemented"); - throw ErrorAlreadySet(); - } + template struct define_operator; - const char* description() const - { return "__error__"; } + struct add_operator_base + { + protected: + static inline void add_method(ExtensionClassBase* target, Function* method, const char* name) + { target->add_method(method, name); } + }; - }; - template - struct roperator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* keywords) const - { - PyErr_SetString(PyExc_TypeError, "operator not implemented"); - throw ErrorAlreadySet(); - } + template + struct choose_op + { + template + struct args : add_operator_base + { + static inline void add(ExtensionClassBase* target) + { + typedef define_operator def_op; + add_method(target, + new typename def_op::template operator_function(), + def_op::name()); + } - const char* description() const - { return "__error__"; } + }; + }; + + template <> + struct choose_op<0> + { + template + struct args + { + static inline void add(ExtensionClassBase*) + { + } - }; + }; + }; + + template + struct choose_unary_op + { + template + struct args : add_operator_base + { + static inline void add(ExtensionClassBase* target) + { + typedef define_operator def_op; + add_method(target, + new typename def_op::template operator_function(), + def_op::name()); + } - static const char * name() { return "__error__"; } - static const char * rname() { return "__error__"; } - }; + }; + }; + + template <> + struct choose_unary_op<0> + { + template + struct args + { + static inline void add(ExtensionClassBase*) + { + } -#define py_define_binary_operators(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : Function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - Tuple args(Ptr(arguments, Ptr::new_ref)); \ - \ - return PY_CONVERSION::to_python( \ - PY_CONVERSION::from_python(args[0].get(), py::Type()) oper \ - PY_CONVERSION::from_python(args[1].get(), py::Type())); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - \ - }; \ - template \ - struct roperator_function : Function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - Tuple args(Ptr(arguments, Ptr::new_ref)); \ - \ - return PY_CONVERSION::to_python( \ - PY_CONVERSION::from_python(args[1].get(), py::Type()) oper \ - PY_CONVERSION::from_python(args[0].get(), py::Type())); \ - } \ - \ - const char* description() const \ - { return "__r" #id "__"; } \ - \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - static const char * rname() { return "__r" #id "__"; } \ - } - -#define py_define_unary_operators(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : Function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - Tuple args(Ptr(arguments, Ptr::new_ref)); \ - \ - return PY_CONVERSION::to_python( \ - oper(PY_CONVERSION::from_python(args[0].get(), py::Type()))); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - } - -#define py_define_conversion_operators(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : Function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - Tuple args(Ptr(arguments, Ptr::new_ref)); \ - \ - return PY_CONVERSION::to_python( \ - oper(PY_CONVERSION::from_python(args[0].get(), py::Type()))); \ - } \ - \ - const char* description() const \ - { return "__" #id "_"; } \ - \ - }; \ - \ - static const char * name() { return "__" #id "_"; } \ - } - - py_define_binary_operators(add, +); - py_define_binary_operators(sub, -); - py_define_binary_operators(mul, *); - py_define_binary_operators(div, /); - py_define_binary_operators(mod, %); - py_define_binary_operators(lshift, <<); - py_define_binary_operators(rshift, >>); - py_define_binary_operators(and, &); - py_define_binary_operators(xor, ^); - py_define_binary_operators(or, |); + }; + }; + + template + struct choose_rop + { + template + struct args : add_operator_base + { + static inline void add(ExtensionClassBase* target) + { + typedef define_operator def_op; + add_method(target, + new typename def_op::template roperator_function(), + def_op::rname()); + } - py_define_unary_operators(neg, -); - py_define_unary_operators(pos, +); - py_define_unary_operators(abs, abs); - py_define_unary_operators(invert, ~); + }; + }; + + template <> + struct choose_rop<0> + { + template + struct args + { + static inline void add(ExtensionClassBase*) + { + } - py_define_conversion_operators(int, int); - py_define_conversion_operators(long, long); - py_define_conversion_operators(float, double); + }; + }; + +#define PY_DEFINE_BINARY_OPERATORS(id, oper) \ + template <> \ + struct define_operator \ + { \ + template \ + struct operator_function : Function \ + { \ + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ + { \ + Tuple args(Ptr(arguments, Ptr::new_ref)); \ + \ + return PY_CONVERSION::to_python( \ + PY_CONVERSION::from_python(args[0].get(), py::Type()) oper \ + PY_CONVERSION::from_python(args[1].get(), py::Type())); \ + } \ + \ + const char* description() const \ + { return "__" #id "__"; } \ + \ + }; \ + template \ + struct roperator_function : Function \ + { \ + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ + { \ + Tuple args(Ptr(arguments, Ptr::new_ref)); \ + \ + return PY_CONVERSION::to_python( \ + PY_CONVERSION::from_python(args[1].get(), py::Type()) oper \ + PY_CONVERSION::from_python(args[0].get(), py::Type())); \ + } \ + \ + const char* description() const \ + { return "__r" #id "__"; } \ + \ + }; \ + \ + static const char * name() { return "__" #id "__"; } \ + static const char * rname() { return "__r" #id "__"; } \ + } -#undef py_define_binary_operators -#undef py_define_unary_operators -#undef py_define_conversion_operators - - template <> - struct define_operator - { - template - struct operator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); +#define PY_DEFINE_UNARY_OPERATORS(id, oper) \ + template <> \ + struct define_operator \ + { \ + template \ + struct operator_function : Function \ + { \ + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ + { \ + Tuple args(Ptr(arguments, Ptr::new_ref)); \ + \ + return PY_CONVERSION::to_python( \ + oper(PY_CONVERSION::from_python(args[0].get(), py::Type()))); \ + } \ + \ + const char* description() const \ + { return "__" #id "__"; } \ + \ + }; \ + \ + static const char * name() { return "__" #id "__"; } \ + } - if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); - throw ArgumentError(); - } +#define PY_DEFINE_CONVERSION_OPERATORS(id, oper) \ + template <> \ + struct define_operator \ + { \ + template \ + struct operator_function : Function \ + { \ + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ + { \ + Tuple args(Ptr(arguments, Ptr::new_ref)); \ + \ + return PY_CONVERSION::to_python( \ + oper(PY_CONVERSION::from_python(args[0].get(), py::Type()))); \ + } \ + \ + const char* description() const \ + { return "__" #id "_"; } \ + \ + }; \ + \ + static const char * name() { return "__" #id "_"; } \ + } - return PY_CONVERSION::to_python( - pow(PY_CONVERSION::from_python(args[0].get(), py::Type()), - PY_CONVERSION::from_python(args[1].get(), py::Type()))); - } + PY_DEFINE_BINARY_OPERATORS(add, +); + PY_DEFINE_BINARY_OPERATORS(sub, -); + PY_DEFINE_BINARY_OPERATORS(mul, *); + PY_DEFINE_BINARY_OPERATORS(div, /); + PY_DEFINE_BINARY_OPERATORS(mod, %); + PY_DEFINE_BINARY_OPERATORS(lshift, <<); + PY_DEFINE_BINARY_OPERATORS(rshift, >>); + PY_DEFINE_BINARY_OPERATORS(and, &); + PY_DEFINE_BINARY_OPERATORS(xor, ^); + PY_DEFINE_BINARY_OPERATORS(or, |); - const char* description() const - { return "__pow__"; } + PY_DEFINE_UNARY_OPERATORS(neg, -); + PY_DEFINE_UNARY_OPERATORS(pos, +); + PY_DEFINE_UNARY_OPERATORS(abs, abs); + PY_DEFINE_UNARY_OPERATORS(invert, ~); - }; + PY_DEFINE_CONVERSION_OPERATORS(int, int); + PY_DEFINE_CONVERSION_OPERATORS(long, long); + PY_DEFINE_CONVERSION_OPERATORS(float, double); - template - struct roperator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); +#undef PY_DEFINE_BINARY_OPERATORS +#undef PY_DEFINE_UNARY_OPERATORS +#undef PY_DEFINE_CONVERSION_OPERATORS - if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); - throw ArgumentError(); - } + template <> + struct define_operator + { + template + struct operator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); - return PY_CONVERSION::to_python( - pow(PY_CONVERSION::from_python(args[1].get(), py::Type()), - PY_CONVERSION::from_python(args[0].get(), py::Type()))); - } + if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type) + { + PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); + throw ArgumentError(); + } - const char* description() const - { return "__rpow__"; } + return PY_CONVERSION::to_python( + pow(PY_CONVERSION::from_python(args[0].get(), py::Type()), + PY_CONVERSION::from_python(args[1].get(), py::Type()))); + } - }; + const char* description() const + { return "__pow__"; } - static const char * name() { return "__pow__"; } - static const char * rname() { return "__rpow__"; } - }; + }; - template <> - struct define_operator - { - template - struct operator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); - PyObject * res = PyTuple_New(2); + template + struct roperator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); - PyTuple_SET_ITEM(res, 0, - PY_CONVERSION::to_python( - PY_CONVERSION::from_python(args[0].get(), py::Type()) / - PY_CONVERSION::from_python(args[1].get(), py::Type()))); - PyTuple_SET_ITEM(res, 1, - PY_CONVERSION::to_python( - PY_CONVERSION::from_python(args[0].get(), py::Type()) % - PY_CONVERSION::from_python(args[1].get(), py::Type()))); + if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type) + { + PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); + throw ArgumentError(); + } - return res; - } + return PY_CONVERSION::to_python( + pow(PY_CONVERSION::from_python(args[1].get(), py::Type()), + PY_CONVERSION::from_python(args[0].get(), py::Type()))); + } - const char* description() const - { return "__divmod__"; } + const char* description() const + { return "__rpow__"; } - }; + }; - template - struct roperator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); - PyObject * res = PyTuple_New(2); + static const char * name() { return "__pow__"; } + static const char * rname() { return "__rpow__"; } + }; - PyTuple_SET_ITEM(res, 0, - PY_CONVERSION::to_python( - PY_CONVERSION::from_python(args[1].get(), py::Type()) / - PY_CONVERSION::from_python(args[0].get(), py::Type()))); - PyTuple_SET_ITEM(res, 1, - PY_CONVERSION::to_python( - PY_CONVERSION::from_python(args[1].get(), py::Type()) % - PY_CONVERSION::from_python(args[0].get(), py::Type()))); + template <> + struct define_operator + { + template + struct operator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); + PyObject * res = PyTuple_New(2); - return res; - } + PyTuple_SET_ITEM(res, 0, + PY_CONVERSION::to_python( + PY_CONVERSION::from_python(args[0].get(), py::Type()) / + PY_CONVERSION::from_python(args[1].get(), py::Type()))); + PyTuple_SET_ITEM(res, 1, + PY_CONVERSION::to_python( + PY_CONVERSION::from_python(args[0].get(), py::Type()) % + PY_CONVERSION::from_python(args[1].get(), py::Type()))); - const char* description() const - { return "__rdivmod__"; } + return res; + } - }; + const char* description() const + { return "__divmod__"; } - static const char * name() { return "__divmod__"; } - static const char * rname() { return "__rdivmod__"; } - }; + }; - template <> - struct define_operator - { - template - struct operator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); + template + struct roperator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); + PyObject * res = PyTuple_New(2); - return PY_CONVERSION::to_python( - (PY_CONVERSION::from_python(args[0].get(), py::Type()) < - PY_CONVERSION::from_python(args[1].get(), py::Type())) ? - - 1 : - (PY_CONVERSION::from_python(args[1].get(), py::Type()) < - PY_CONVERSION::from_python(args[0].get(), py::Type())) ? - 1 : - 0) ; - } + PyTuple_SET_ITEM(res, 0, + PY_CONVERSION::to_python( + PY_CONVERSION::from_python(args[1].get(), py::Type()) / + PY_CONVERSION::from_python(args[0].get(), py::Type()))); + PyTuple_SET_ITEM(res, 1, + PY_CONVERSION::to_python( + PY_CONVERSION::from_python(args[1].get(), py::Type()) % + PY_CONVERSION::from_python(args[0].get(), py::Type()))); - const char* description() const - { return "__cmp__"; } + return res; + } - }; + const char* description() const + { return "__rdivmod__"; } - template - struct roperator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); + }; - return PY_CONVERSION::to_python( - (PY_CONVERSION::from_python(args[1].get(), py::Type()) < - PY_CONVERSION::from_python(args[0].get(), py::Type())) ? - - 1 : - (PY_CONVERSION::from_python(args[0].get(), py::Type()) < - PY_CONVERSION::from_python(args[1].get(), py::Type())) ? - 1 : - 0) ; - } + static const char * name() { return "__divmod__"; } + static const char * rname() { return "__rdivmod__"; } + }; - const char* description() const - { return "__rcmp__"; } + template <> + struct define_operator + { + template + struct operator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); - }; + return PY_CONVERSION::to_python( + (PY_CONVERSION::from_python(args[0].get(), py::Type()) < + PY_CONVERSION::from_python(args[1].get(), py::Type())) ? + - 1 : + (PY_CONVERSION::from_python(args[1].get(), py::Type()) < + PY_CONVERSION::from_python(args[0].get(), py::Type())) ? + 1 : + 0) ; + } - static const char * name() { return "__cmp__"; } - static const char * rname() { return "__rcmp__"; } - }; + const char* description() const + { return "__cmp__"; } - template <> - struct define_operator - { - template - struct operator_function : Function - { - PyObject* do_call(PyObject* arguments, PyObject* keywords) const - { - Tuple args(Ptr(arguments, Ptr::new_ref)); + }; - std::strstream s; - s << PY_CONVERSION::from_python(args[0].get(), py::Type()); + template + struct roperator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); - return PY_CONVERSION::to_python(const_cast(s.str())); - } + return PY_CONVERSION::to_python( + (PY_CONVERSION::from_python(args[1].get(), py::Type()) < + PY_CONVERSION::from_python(args[0].get(), py::Type())) ? + - 1 : + (PY_CONVERSION::from_python(args[0].get(), py::Type()) < + PY_CONVERSION::from_python(args[1].get(), py::Type())) ? + 1 : + 0) ; + } - const char* description() const - { return "__str__"; } + const char* description() const + { return "__rcmp__"; } - }; + }; - static const char * name() { return "__str__"; } - }; + static const char * name() { return "__cmp__"; } + static const char * rname() { return "__rcmp__"; } + }; + + template <> + struct define_operator + { + template + struct operator_function : Function + { + PyObject* do_call(PyObject* arguments, PyObject*) const + { + Tuple args(Ptr(arguments, Ptr::new_ref)); + +#if !defined(__GNUC__) || defined(__SGI_STL_PORT) + std::ostringstream s; +#else + std::strstream s; +#endif + s << PY_CONVERSION::from_python(args[0].get(), py::Type()); + +#if !defined(__GNUC__) || defined(__SGI_STL_PORT) + return PY_CONVERSION::to_python(s.str()); +#else + return PY_CONVERSION::to_python(const_cast(s.str())); +#endif + } + + const char* description() const + { return "__str__"; } + + }; + + static const char * name() { return "__str__"; } + }; } // namespace detail