| 1 | /* ------------------------------------------------------------ |
| 2 | * Overloaded operator support |
| 3 | * ------------------------------------------------------------ */ |
| 4 | |
| 5 | |
| 6 | #ifdef __cplusplus |
| 7 | %define %pybinoperator(pyname,oper) |
| 8 | %rename(pyname) oper; |
| 9 | %pythonmaybecall oper; |
| 10 | %enddef |
| 11 | |
| 12 | %pybinoperator(__add__, *::operator+); |
| 13 | %pybinoperator(__pos__, *::operator+()); |
| 14 | %pybinoperator(__pos__, *::operator+() const); |
| 15 | %pybinoperator(__sub__, *::operator-); |
| 16 | %pybinoperator(__neg__, *::operator-()); |
| 17 | %pybinoperator(__neg__, *::operator-() const); |
| 18 | %pybinoperator(__mul__, *::operator*); |
| 19 | %pybinoperator(__div__, *::operator/); |
| 20 | %pybinoperator(__mod__, *::operator%); |
| 21 | %pybinoperator(__lshift__, *::operator<<); |
| 22 | %pybinoperator(__rshift__, *::operator>>); |
| 23 | %pybinoperator(__and__, *::operator&); |
| 24 | %pybinoperator(__or__, *::operator|); |
| 25 | %pybinoperator(__xor__, *::operator^); |
| 26 | %pybinoperator(__lt__, *::operator<); |
| 27 | %pybinoperator(__le__, *::operator<=); |
| 28 | %pybinoperator(__gt__, *::operator>); |
| 29 | %pybinoperator(__ge__, *::operator>=); |
| 30 | %pybinoperator(__eq__, *::operator==); |
| 31 | %pybinoperator(__ne__, *::operator!=); |
| 32 | |
| 33 | %define %pybinoperation(oper) |
| 34 | %pythonmaybecall __ ## oper ## __; |
| 35 | %pythonmaybecall __r ## oper ## __; |
| 36 | %enddef |
| 37 | |
| 38 | %pybinoperation(add); |
| 39 | %pybinoperation(pos); |
| 40 | %pybinoperation(pos); |
| 41 | %pybinoperation(sub); |
| 42 | %pybinoperation(neg); |
| 43 | %pybinoperation(neg); |
| 44 | %pybinoperation(mul); |
| 45 | %pybinoperation(div); |
| 46 | %pybinoperation(mod); |
| 47 | %pybinoperation(lshift); |
| 48 | %pybinoperation(rshift); |
| 49 | %pybinoperation(and); |
| 50 | %pybinoperation(or); |
| 51 | %pybinoperation(xor); |
| 52 | %pybinoperation(lt); |
| 53 | %pybinoperation(le); |
| 54 | %pybinoperation(gt); |
| 55 | %pybinoperation(ge); |
| 56 | %pybinoperation(eq); |
| 57 | %pybinoperation(ne); |
| 58 | |
| 59 | |
| 60 | /* Special cases */ |
| 61 | %rename(__invert__) *::operator~; |
| 62 | %rename(__call__) *::operator(); |
| 63 | |
| 64 | /* Ignored operators */ |
| 65 | %ignorewarn("361:operator! ignored") operator!; |
| 66 | %ignorewarn("381:operator&& ignored") operator&&; |
| 67 | %ignorewarn("382:operator|| ignored") operator||; |
| 68 | %ignorewarn("362:operator= ignored") *::operator=; |
| 69 | %ignorewarn("383:operator++ ignored") *::operator++; |
| 70 | %ignorewarn("384:operator-- ignored") *::operator--; |
| 71 | %ignorewarn("386:operator->* ignored") *::operator->*; |
| 72 | %ignorewarn("389:operator[] ignored (consider using %extend)") *::operator[]; |
| 73 | |
| 74 | |
| 75 | |
| 76 | /* |
| 77 | Inplace operator declarations. |
| 78 | |
| 79 | They translate the inplace C++ operators (+=, -=, ...) into the |
| 80 | corresponding python equivalents(__iadd__,__isub__), etc, |
| 81 | disabling the ownership of the input 'self' pointer, and assigning |
| 82 | it to the returning object: |
| 83 | |
| 84 | %feature("self:disown") *::Operator; |
| 85 | %feature("new") *::Operator; |
| 86 | |
| 87 | This makes the most common case safe, ie: |
| 88 | |
| 89 | A& A::operator+=(int i) { ...; return *this; } |
| 90 | ^^^^ ^^^^^^ |
| 91 | |
| 92 | will work fine, even when the resulting python object shares the |
| 93 | 'this' pointer with the input one. The input object is usually |
| 94 | deleted after the operation, including the shared 'this' pointer, |
| 95 | producing 'strange' seg faults, as reported by Lucriz |
| 96 | (lucriz@sitilandia.it). |
| 97 | |
| 98 | If you have an interface that already takes care of that, ie, you |
| 99 | already are using inplace operators and you are not getting |
| 100 | seg. faults, with the new scheme you could end with 'free' elements |
| 101 | that never get deleted (maybe, not sure, it depends). But if that is |
| 102 | the case, you could recover the old behaviour using |
| 103 | |
| 104 | %feature("self:disown","") A::operator+=; |
| 105 | %feature("new","") A::operator+=; |
| 106 | |
| 107 | which recovers the old behaviour for the class 'A', or if you are |
| 108 | 100% sure your entire system works fine in the old way, use: |
| 109 | |
| 110 | %feature("self:disown","") *::operator+=; |
| 111 | %feature("new","") *::operator+=; |
| 112 | |
| 113 | */ |
| 114 | |
| 115 | %define %swig_inplace_oper(Oper, PyOper) |
| 116 | %feature("self:disown") *::Oper; |
| 117 | %feature("new") *::Oper; |
| 118 | %rename(__##PyOper##__) *::Oper; |
| 119 | %enddef |
| 120 | |
| 121 | %swig_inplace_oper(operator +=, iadd); |
| 122 | %swig_inplace_oper(operator -=, isub); |
| 123 | %swig_inplace_oper(operator *=, imul); |
| 124 | %swig_inplace_oper(operator /=, idiv); |
| 125 | %swig_inplace_oper(operator %=, imod); |
| 126 | %swig_inplace_oper(operator &=, iand); |
| 127 | %swig_inplace_oper(operator |=, ior); |
| 128 | %swig_inplace_oper(operator ^=, ixor); |
| 129 | %swig_inplace_oper(operator <<=, ilshift); |
| 130 | %swig_inplace_oper(operator >>=, irshift); |
| 131 | |
| 132 | #endif |