/tags/rel-1.3.35/Examples/test-suite/operator_overload.i
Swig | 352 lines | 280 code | 46 blank | 26 comment | 0 complexity | 9ed8871d0bbdb880f882d2cb07d1f36c MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
1/* File : operator_overload.i */
2/*
3This is a test of all the possible operator overloads
4
5see bottom for a set of possible tests
6*/
7%module operator_overload
8
9#if defined(SWIGPYTHON)
10%warnfilter(SWIGWARN_IGNORE_OPERATOR_EQ,
11 SWIGWARN_IGNORE_OPERATOR_INDEX,
12 SWIGWARN_IGNORE_OPERATOR_PLUSPLUS,
13 SWIGWARN_IGNORE_OPERATOR_MINUSMINUS,
14 SWIGWARN_IGNORE_OPERATOR_LAND,
15 SWIGWARN_IGNORE_OPERATOR_LOR);
16#endif
17
18#if !defined(SWIGLUA) && !defined(SWIGR)
19%rename(Equal) operator =;
20%rename(PlusEqual) operator +=;
21%rename(MinusEqual) operator -=;
22%rename(MultiplyEqual) operator *=;
23%rename(DivideEqual) operator /=;
24%rename(PercentEqual) operator %=;
25%rename(Plus) operator +;
26%rename(Minus) operator -;
27%rename(Multiply) operator *;
28%rename(Divide) operator /;
29%rename(Percent) operator %;
30%rename(Not) operator !;
31%rename(IndexIntoConst) operator[](unsigned idx) const;
32%rename(IndexInto) operator[](unsigned idx);
33%rename(Functor) operator ();
34%rename(EqualEqual) operator ==;
35%rename(NotEqual) operator !=;
36%rename(LessThan) operator <;
37%rename(LessThanEqual) operator <=;
38%rename(GreaterThan) operator >;
39%rename(GreaterThanEqual) operator >=;
40%rename(And) operator &&;
41%rename(Or) operator ||;
42%rename(PlusPlusPrefix) operator++();
43%rename(PlusPlusPostfix) operator++(int);
44%rename(MinusMinusPrefix) operator--();
45%rename(MinusMinusPostfix) operator--(int);
46#endif
47
48#ifdef SWIGCSHARP
49%csmethodmodifiers operator++() "protected";
50%csmethodmodifiers operator++(int) "private";
51%csmethodmodifiers operator--() "private";
52%csmethodmodifiers operator--(int) "protected";
53%typemap(cscode) Op %{
54 public static Op operator++(Op op) {
55 // Unlike C++, operator++ must not modify the parameter and both prefix and postfix operations call this method
56 Op newOp = new Op(op.i);
57 newOp.PlusPlusPostfix(0);
58 return newOp;
59 }
60 public static Op operator--(Op op) {
61 // Unlike C++, operator-- must not modify the parameter and both prefix and postfix operations call this method
62 Op newOp = new Op(op.i);
63 newOp.MinusMinusPrefix();
64 return newOp;
65 }
66%}
67#endif
68
69#ifdef SWIGPHP
70%rename(AndOperator) operator &&;
71%rename(OrOperator) operator ||;
72#endif
73
74%rename(IntCast) operator int();
75%rename(DoubleCast) operator double();
76
77%inline %{
78
79#if defined(_MSC_VER)
80 #include <iso646.h> /* for named logical operator, eg 'operator or' */
81#endif
82
83#include <assert.h>
84
85class Op {
86public:
87 int i;
88 Op(int a=0) : i(a)
89 {}
90 Op(const Op& o) : i(o.i)
91 {}
92 virtual ~Op()
93 {}
94
95 friend Op operator &&(const Op& a,const Op& b){return Op(a.i&&b.i);}
96 friend Op operator or(const Op& a,const Op& b){return Op(a.i||b.i);}
97
98 Op &operator=(const Op& o) {
99 i=o.i;
100 return *this;
101 }
102 // +=,-=... are member fns
103 void operator+=(const Op& o){ i+=o.i;}
104 void operator-=(const Op& o){ i-=o.i;}
105 void operator*=(const Op& o){ i*=o.i;}
106 void operator/=(const Op& o){ i/=o.i;}
107 void operator%=(const Op& o){ i%=o.i;}
108 // the +,-,*,... are friends
109 // (just to make life harder)
110 friend Op operator+(const Op& a,const Op& b){return Op(a.i+b.i);}
111 friend Op operator-(const Op& a,const Op& b);
112 friend Op operator*(const Op& a,const Op& b){return Op(a.i*b.i);}
113 friend Op operator/(const Op& a,const Op& b){return Op(a.i/b.i);}
114 friend Op operator%(const Op& a,const Op& b){return Op(a.i%b.i);}
115
116 // unary operators
117 Op operator-() const {return Op(-i);}
118 bool operator !() const {return !(i);}
119
120 // overloading the [] operator
121 // need 2 versions: get & set
122 // note: C++ can be a little mixed up upon which version it calls
123 // most of the time it calls the second version
124 int operator[](unsigned idx)const
125 { if (idx==0) return i; return 0;}
126 int& operator[](unsigned idx)
127 { if (idx==0) return i; static int j;j=0; return j;}
128
129 // overloading the () operator
130 // this can have many parameters so we will test this
131 int operator()(int a=0){return i+a;}
132 int operator()(int a,int b){return i+a+b;}
133
134 // increment/decrement operators
135 Op& operator++() {++i; return *this;} // prefix ++
136 Op operator++(int) {Op o = *this; ++(*this); return o;} // postfix ++
137 Op& operator--() {--i; return *this;} // prefix --
138 Op operator--(int) {Op o = *this; --(*this); return o;} // postfix --
139
140 // TODO: <<,<<=
141
142 // cast operators
143 operator double() { return i; }
144 virtual operator int() { return i; }
145
146 // This method just checks that the operators are implemented correctly
147 static void sanity_check();
148};
149
150// just to complicate matters
151// we have a couple of non class operators
152inline bool operator==(const Op& a,const Op& b){return a.i==b.i;}
153inline bool operator!=(const Op& a,const Op& b){return a.i!=b.i;}
154inline bool operator< (const Op& a,const Op& b){return a.i<b.i;}
155inline bool operator<=(const Op& a,const Op& b){return a.i<=b.i;}
156inline bool operator> (const Op& a,const Op& b){return a.i>b.i;}
157inline bool operator>=(const Op& a,const Op& b){return a.i>=b.i;}
158
159%}
160
161%{
162 // This one is not declared inline as VC++7.1 gets mixed up with the unary operator-
163 Op operator-(const Op& a,const Op& b){return Op(a.i-b.i);}
164%}
165
166// in order to wrapper this correctly
167// we need to extend the class
168// to make the friends & non members part of the class
169%extend Op{
170 Op operator &&(const Op& b){return Op($self->i&&b.i);}
171 Op operator or(const Op& b){return Op($self->i||b.i);}
172
173 Op operator+(const Op& b){return Op($self->i+b.i);}
174 Op operator-(const Op& b){return Op($self->i-b.i);}
175 Op operator*(const Op& b){return Op($self->i*b.i);}
176 Op operator/(const Op& b){return Op($self->i/b.i);}
177 Op operator%(const Op& b){return Op($self->i%b.i);}
178
179 bool operator==(const Op& b){return $self->i==b.i;}
180 bool operator!=(const Op& b){return $self->i!=b.i;}
181 bool operator< (const Op& b){return $self->i<b.i;}
182 bool operator<=(const Op& b){return $self->i<=b.i;}
183 bool operator> (const Op& b){return $self->i>b.i;}
184 bool operator>=(const Op& b){return $self->i>=b.i;}
185
186 // subtraction with reversed arguments
187 Op __rsub__(const int b){return Op(b - $self->i);}
188
189 // we also add the __str__() fn to the class
190 // this allows it to be converted to a string (so it can be printed)
191 const char* __str__()
192 {
193 static char buffer[255];
194 sprintf(buffer,"Op(%d)",$self->i);
195 return buffer;
196 }
197 // to get the [] operator working correctly we need to extend with two function
198 // __getitem__ & __setitem__
199 int __getitem__(unsigned i)
200 { return (*$self)[i]; }
201 void __setitem__(unsigned i,int v)
202 { (*$self)[i]=v; }
203}
204
205/*
206Suggested list of operator overloads (mainly from python)
207
208Operators overloaded with their C++ equivalent
209__add__,__sub__,__mul__,__div__,__mod__ +,-,*,/,%
210__iadd__,__isub__,__imul__,__idiv__,__imod__ +=,-=,*=,/=,%=
211
212__eq__,__ne__,__lt__,__le__,__gt__,__ge__ ==,!=,<,<=,>,>=
213__not__,__neg__ unary !, unary -
214__and__,__or__,__xor__ logical and,logical or,logical xor
215__rshift__,__lshift__ >>,<<
216
217__getitem__,__setitem__ for operator[]
218
219Operators overloaded without C++ equivilents
220__pow__ for power operator
221__str__ converts object to a string (should return a const char*)
222__concat__ for contatenation (if language supports)
223
224*/
225
226%inline %{
227class OpDerived : public Op {
228public:
229 OpDerived(int a=0) : Op(a)
230 {}
231
232 // overloaded
233 virtual operator int() { return i*2; }
234};
235%}
236
237
238%{
239
240#include <assert.h>
241
242void Op::sanity_check()
243{
244 // test routine:
245 Op a;
246 Op b=5;
247 Op c=b; // copy construct
248 Op d=2;
249 Op dd=d; // assignment operator
250
251 // test equality
252 assert(a!=b);
253 assert(b==c);
254 assert(a!=d);
255 assert(d==dd);
256
257 // test <
258 assert(a<b);
259 assert(a<=b);
260 assert(b<=c);
261 assert(b>=c);
262 assert(b>d);
263 assert(b>=d);
264
265 // test +=
266 Op e=3;
267 e+=d;
268 assert(e==b);
269 e-=c;
270 assert(e==a);
271 e=Op(1);
272 e*=b;
273 assert(e==c);
274 e/=d;
275 assert(e==d);
276 e%=c;
277 assert(e==d);
278
279 // test +
280 Op f(1),g(1);
281 assert(f+g==Op(2));
282 assert(f-g==Op(0));
283 assert(f*g==Op(1));
284 assert(f/g==Op(1));
285 assert(f%g==Op(0));
286
287 // test unary operators
288 assert(!a==true);
289 assert(!b==false);
290 assert(-a==a);
291 assert(-b==Op(-5));
292
293 // test []
294 Op h=3;
295 assert(h[0]==3);
296 assert(h[1]==0);
297 h[0]=2; // set
298 assert(h[0]==2);
299 h[1]=2; // ignored
300 assert(h[0]==2);
301 assert(h[1]==0);
302
303 // test ()
304 Op i=3;
305 assert(i()==3);
306 assert(i(1)==4);
307 assert(i(1,2)==6);
308
309 // plus add some code to check the __str__ fn
310 //assert(str(Op(1))=="Op(1)");
311 //assert(str(Op(-3))=="Op(-3)");
312
313 // test ++ and --
314 Op j(100);
315 int original = j.i;
316 {
317 Op newOp = j++;
318 int newInt = original++;
319 assert(j.i == original);
320 assert(newOp.i == newInt);
321 }
322 {
323 Op newOp = j--;
324 int newInt = original--;
325 assert(j.i == original);
326 assert(newOp.i == newInt);
327 }
328 {
329 Op newOp = ++j;
330 int newInt = ++original;
331 assert(j.i == original);
332 assert(newOp.i == newInt);
333 }
334 {
335 Op newOp = --j;
336 int newInt = --original;
337 assert(j.i == original);
338 assert(newOp.i == newInt);
339 }
340
341 // cast operators
342 Op k=3;
343 int check_k = k;
344 assert (check_k == 3);
345
346 Op l=4;
347 double check_l = l;
348 assert (check_l == 4);
349}
350
351%}
352