Home | History | Annotate | Download | only in python
      1 /* ------------------------------------------------------------
      2  * Overloaded operator support
      3 
      4  The directives in this file apply whether or not you use the
      5  -builtin option to SWIG, but operator overloads are particularly
      6  attractive when using -builtin, because they are much faster
      7  than named methods.
      8 
      9  If you're using the -builtin option to SWIG, and you want to define
     10  python operator overloads beyond the defaults defined in this file,
     11  here's what you need to know:
     12 
     13  There are two ways to define a python slot function: dispatch to a
     14  statically defined function; or dispatch to a method defined on the
     15  operand.
     16 
     17  To dispatch to a statically defined function, use %feature("python:<slot>"),
     18  where <slot> is the name of a field in a PyTypeObject, PyNumberMethods,
     19  PyMappingMethods, PySequenceMethods, or PyBufferProcs.  For example:
     20 
     21    %{
     22 
     23    static long myHashFunc (PyObject *pyobj) {
     24      MyClass *cobj;
     25      // Convert pyobj to cobj
     26      return (cobj->field1 * (cobj->field2 << 7));
     27    }
     28 
     29    %}
     30 
     31    %feature("python:tp_hash") MyClass "myHashFunc";
     32 
     33  NOTE: It is the responsibility of the programmer (that's you) to ensure
     34  that a statically defined slot function has the correct signature.
     35 
     36  If, instead, you want to dispatch to an instance method, you can
     37  use %feature("python:slot").  For example:
     38 
     39    class MyClass {
     40      public:
     41        long myHashFunc () const;
     42        ...
     43    };
     44 
     45    %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
     46 
     47  NOTE: Some python slots use a method signature which does not
     48  match the signature of SWIG-wrapped methods.  For those slots,
     49  SWIG will automatically generate a "closure" function to re-marshall
     50  the arguments before dispatching to the wrapped method.  Setting
     51  the "functype" attribute of the feature enables SWIG to generate
     52  a correct closure function.
     53 
     54  --------------------------------------------------------------
     55 
     56  The tp_richcompare slot is a special case: SWIG automatically generates
     57  a rich compare function for all wrapped types.  If a type defines C++
     58  operator overloads for comparison (operator==, operator<, etc.), they
     59  will be called from the generated rich compare function.  If you
     60  want to explicitly choose a method to handle a certain comparison
     61  operation, you may use %feature("python:slot") like this:
     62 
     63    class MyClass {
     64      public:
     65        bool lessThan (const MyClass& x) const;
     66        ...
     67    };
     68 
     69    %feature("python:slot", "Py_LT") MyClass::lessThan;
     70 
     71  ... where "Py_LT" is one of the rich comparison opcodes defined in the
     72  python header file object.h.
     73 
     74  If there's no method defined to handle a particular comparsion operation,
     75  the default behavior is to compare pointer values of the wrapped
     76  C++ objects.
     77 
     78  --------------------------------------------------------------
     79 
     80 
     81  For more information about python slots, including their names and
     82  signatures, you may refer to the python documentation :
     83 
     84    http://docs.python.org/c-api/typeobj.html
     85 
     86  * ------------------------------------------------------------ */
     87 
     88 
     89 #ifdef __cplusplus
     90 
     91 #if defined(SWIGPYTHON_BUILTIN)
     92 #define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:slot", #slt, functype=#functp) oper; %feature("python:slot", #slt, functype=#functp) pyname;
     93 #define %pycompare(pyname,oper,comptype) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:compare", #comptype) oper; %feature("python:compare", #comptype) pyname;
     94 #else
     95 #define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper
     96 #define %pycompare(pyname,oper,comptype) %pybinoperator(pyname,oper,,comptype)
     97 #endif
     98 
     99 %pybinoperator(__add__,      *::operator+,		binaryfunc, nb_add);
    100 %pybinoperator(__pos__,      *::operator+(),		unaryfunc, nb_positive);
    101 %pybinoperator(__pos__,      *::operator+() const,	unaryfunc, nb_positive);
    102 %pybinoperator(__sub__,      *::operator-,		binaryfunc, nb_subtract);
    103 %pybinoperator(__neg__,      *::operator-(),		unaryfunc, nb_negative);
    104 %pybinoperator(__neg__,      *::operator-() const,	unaryfunc, nb_negative);
    105 %pybinoperator(__mul__,      *::operator*,		binaryfunc, nb_multiply);
    106 %pybinoperator(__div__,      *::operator/,		binaryfunc, nb_div);
    107 %pybinoperator(__mod__,      *::operator%,		binaryfunc, nb_remainder);
    108 %pybinoperator(__lshift__,   *::operator<<,		binaryfunc, nb_lshift);
    109 %pybinoperator(__rshift__,   *::operator>>,		binaryfunc, nb_rshift);
    110 %pybinoperator(__and__,      *::operator&,		binaryfunc, nb_and);
    111 %pybinoperator(__or__,       *::operator|,		binaryfunc, nb_or);
    112 %pybinoperator(__xor__,      *::operator^,		binaryfunc, nb_xor);
    113 %pycompare(__lt__,           *::operator<,		Py_LT);
    114 %pycompare(__le__,           *::operator<=,		Py_LE);
    115 %pycompare(__gt__,           *::operator>,		Py_GT);
    116 %pycompare(__ge__,           *::operator>=,		Py_GE);
    117 %pycompare(__eq__,           *::operator==,		Py_EQ);
    118 %pycompare(__ne__,           *::operator!=,		Py_NE);
    119 
    120 %feature("python:slot", "nb_truediv", functype="binaryfunc") *::operator/;
    121 
    122 /* Special cases */
    123 %rename(__invert__)     *::operator~;
    124 %feature("python:slot", "nb_invert", functype="unaryfunc") *::operator~;
    125 %rename(__call__)       *::operator();
    126 %feature("python:slot", "tp_call", functype="ternarycallfunc") *::operator();
    127 
    128 #if defined(SWIGPYTHON_BUILTIN)
    129 %pybinoperator(__nonzero__,   *::operator bool,		inquiry, nb_nonzero);
    130 #else
    131 %feature("shadow")      *::operator bool %{
    132 def __nonzero__(self):
    133     return $action(self)
    134 __bool__ = __nonzero__
    135 %};
    136 %rename(__nonzero__)    *::operator bool;
    137 #endif
    138 
    139 /* Ignored operators */
    140 %ignoreoperator(LNOT)       operator!;
    141 %ignoreoperator(LAND)       operator&&;
    142 %ignoreoperator(LOR)        operator||;
    143 %ignoreoperator(EQ)         *::operator=;
    144 %ignoreoperator(PLUSPLUS)   *::operator++;
    145 %ignoreoperator(MINUSMINUS) *::operator--;
    146 %ignoreoperator(ARROWSTAR)  *::operator->*;
    147 %ignoreoperator(INDEX)      *::operator[];
    148 
    149 /*
    150   Inplace operator declarations.
    151 
    152   They translate the inplace C++ operators (+=, -=, ...)  into the
    153   corresponding python equivalents(__iadd__,__isub__), etc,
    154   disabling the ownership of the input 'self' pointer, and assigning
    155   it to the returning object:
    156 
    157      %feature("del") *::Operator;
    158      %feature("new") *::Operator;
    159 
    160   This makes the most common case safe, ie:
    161 
    162      A&  A::operator+=(int i) { ...; return *this; }
    163     ^^^^                                    ^^^^^^
    164 
    165   will work fine, even when the resulting python object shares the
    166   'this' pointer with the input one. The input object is usually
    167   deleted after the operation, including the shared 'this' pointer,
    168   producing 'strange' seg faults, as reported by Lucriz
    169   (lucriz (at) sitilandia.it).
    170 
    171   If you have an interface that already takes care of that, ie, you
    172   already are using inplace operators and you are not getting
    173   seg. faults, with the new scheme you could end with 'free' elements
    174   that never get deleted (maybe, not sure, it depends). But if that is
    175   the case, you could recover the old behaviour using
    176 
    177      %feature("del","") A::operator+=;
    178      %feature("new","") A::operator+=;
    179 
    180   which recovers the old behaviour for the class 'A', or if you are
    181   100% sure your entire system works fine in the old way, use:
    182 
    183     %feature("del","") *::operator+=;
    184     %feature("new","") *::operator+=;
    185 
    186 */
    187 
    188 #if defined(SWIGPYTHON_BUILTIN)
    189 #define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %feature("python:slot", #slt, functype=#functp) Oper; %rename(SwigPyOper) Oper
    190 #else
    191 #define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %rename(SwigPyOper) Oper
    192 #endif
    193 
    194 %pyinplaceoper(__iadd__   , *::operator +=,	binaryfunc, nb_inplace_add);
    195 %pyinplaceoper(__isub__   , *::operator -=,	binaryfunc, nb_inplace_subtract);
    196 %pyinplaceoper(__imul__   , *::operator *=,	binaryfunc, nb_inplace_multiply);
    197 %pyinplaceoper(__idiv__   , *::operator /=,	binaryfunc, nb_inplace_divide);
    198 %pyinplaceoper(__imod__   , *::operator %=,	binaryfunc, nb_inplace_remainder);
    199 %pyinplaceoper(__iand__   , *::operator &=,	binaryfunc, nb_inplace_and);
    200 %pyinplaceoper(__ior__    , *::operator |=,	binaryfunc, nb_inplace_or);
    201 %pyinplaceoper(__ixor__   , *::operator ^=,	binaryfunc, nb_inplace_xor);
    202 %pyinplaceoper(__ilshift__, *::operator <<=,	binaryfunc, nb_inplace_lshift);
    203 %pyinplaceoper(__irshift__, *::operator >>=,	binaryfunc, nb_inplace_rshift);
    204 
    205 
    206 /* Finally, in python we need to mark the binary operations to fail as
    207  'maybecall' methods */
    208 
    209 #define %pybinopermaybecall(oper) %pythonmaybecall __ ## oper ## __;  %pythonmaybecall __r ## oper ## __
    210 
    211 %pybinopermaybecall(add);
    212 %pybinopermaybecall(pos);
    213 %pybinopermaybecall(pos);
    214 %pybinopermaybecall(sub);
    215 %pybinopermaybecall(neg);
    216 %pybinopermaybecall(neg);
    217 %pybinopermaybecall(mul);
    218 %pybinopermaybecall(div);
    219 %pybinopermaybecall(mod);
    220 %pybinopermaybecall(lshift);
    221 %pybinopermaybecall(rshift);
    222 %pybinopermaybecall(and);
    223 %pybinopermaybecall(or);
    224 %pybinopermaybecall(xor);
    225 %pybinopermaybecall(lt);
    226 %pybinopermaybecall(le);
    227 %pybinopermaybecall(gt);
    228 %pybinopermaybecall(ge);
    229 %pybinopermaybecall(eq);
    230 %pybinopermaybecall(ne);
    231 
    232 #endif
    233 
    234 
    235 
    236