From f055f9e60277ab2753ceb6236c9e11bd280da361 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 15 Nov 2000 17:29:37 +0000 Subject: [PATCH] Added commentary, numerous formatting tweaks [SVN r8222] --- operators.h | 229 +++++++++++++++++++++++++++------------------------- 1 file changed, 121 insertions(+), 108 deletions(-) diff --git a/operators.h b/operators.h index 86df0d4f..527b4cd7 100644 --- a/operators.h +++ b/operators.h @@ -14,6 +14,7 @@ namespace detail { template struct define_operator; + // Base class which grants access to ExtensionClassBase::add_method() to its derived classes struct add_operator_base { protected: @@ -21,6 +22,17 @@ namespace detail { { target->add_method(method, name); } }; +// +// choose_op, choose_unary_op, and choose_rop +// +// These templates use "poor man's partial specialization" to generate the +// appropriate add_method() call (if any) for a given operator and argument set. +// +// Usage: +// choose_op<(which & op_add)>::template args::add(ext_class); +// +// (see ExtensionClass<>::def_operators() for more examples). +// template struct choose_op { @@ -37,7 +49,8 @@ namespace detail { }; }; - + + // specialization for 0 has no effect template <> struct choose_op<0> { @@ -68,6 +81,7 @@ namespace detail { }; }; + // specialization for 0 has no effect template <> struct choose_unary_op<0> { @@ -98,6 +112,7 @@ namespace detail { }; }; + // specialization for 0 has no effect template <> struct choose_rop<0> { @@ -111,91 +126,89 @@ namespace detail { }; }; -#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_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 "__"; } \ + 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 "_"; } \ + 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, +); @@ -225,22 +238,22 @@ namespace detail { template <> struct define_operator { - template + template struct operator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const { Tuple args(Ptr(arguments, Ptr::new_ref)); - if(args.size() == 3 && args[2]->ob_type != Py_None->ob_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 PY_CONVERSION::to_python( - pow(PY_CONVERSION::from_python(args[0].get(), py::Type()), - PY_CONVERSION::from_python(args[1].get(), py::Type()))); + pow(PY_CONVERSION::from_python(args[0].get(), py::Type()), + PY_CONVERSION::from_python(args[1].get(), py::Type()))); } const char* description() const @@ -248,22 +261,22 @@ namespace detail { }; - template + template struct roperator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const { Tuple args(Ptr(arguments, Ptr::new_ref)); - if(args.size() == 3 && args[2]->ob_type != Py_None->ob_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 PY_CONVERSION::to_python( - pow(PY_CONVERSION::from_python(args[1].get(), py::Type()), - PY_CONVERSION::from_python(args[0].get(), py::Type()))); + pow(PY_CONVERSION::from_python(args[1].get(), py::Type()), + PY_CONVERSION::from_python(args[0].get(), py::Type()))); } const char* description() const @@ -278,7 +291,7 @@ namespace detail { template <> struct define_operator { - template + template struct operator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const @@ -288,12 +301,12 @@ namespace detail { 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()))); + 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()))); + PY_CONVERSION::from_python(args[0].get(), py::Type()) % + PY_CONVERSION::from_python(args[1].get(), py::Type()))); return res; } @@ -303,7 +316,7 @@ namespace detail { }; - template + template struct roperator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const @@ -313,12 +326,12 @@ namespace detail { 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()))); + 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()))); + PY_CONVERSION::from_python(args[1].get(), py::Type()) % + PY_CONVERSION::from_python(args[0].get(), py::Type()))); return res; } @@ -335,7 +348,7 @@ namespace detail { template <> struct define_operator { - template + template struct operator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const @@ -343,11 +356,11 @@ namespace detail { 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())) ? + (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())) ? + (PY_CONVERSION::from_python(args[1].get(), py::Type()) < + PY_CONVERSION::from_python(args[0].get(), py::Type())) ? 1 : 0) ; } @@ -357,7 +370,7 @@ namespace detail { }; - template + template struct roperator_function : Function { PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const @@ -365,11 +378,11 @@ namespace detail { 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())) ? + (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())) ? + (PY_CONVERSION::from_python(args[0].get(), py::Type()) < + PY_CONVERSION::from_python(args[1].get(), py::Type())) ? 1 : 0) ; }