Commit | Line | Data |
---|---|---|
920dae64 AT |
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 |