import source from 1.3.40
[external/swig.git] / Examples / test-suite / operator_overload.i
1 /* File : operator_overload.i */
2 /*
3 This is a test of all the possible operator overloads
4
5 see 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 #ifdef SWIG_ALLEGRO_CL
75 %{
76 #include <stdio.h>
77 %}
78 #endif
79
80 %rename(IntCast) operator int();
81 %rename(DoubleCast) operator double();
82
83 %inline %{
84
85 #if defined(_MSC_VER)
86   #include <iso646.h> /* for named logical operator, eg 'operator or' */
87 #endif
88
89 #include <assert.h>
90
91 class Op {
92 public:
93   int i;
94   Op(int a=0) : i(a)
95   {}
96   Op(const Op& o) : i(o.i)
97   {}
98   virtual ~Op()
99   {}
100
101   friend Op operator &&(const Op& a,const Op& b){return Op(a.i&&b.i);}
102   friend Op operator or(const Op& a,const Op& b){return Op(a.i||b.i);}
103
104   Op &operator=(const Op& o) {
105     i=o.i;
106     return *this;
107   }
108   // +=,-=... are member fns
109   void operator+=(const Op& o){ i+=o.i;}
110   void operator-=(const Op& o){ i-=o.i;}
111   void operator*=(const Op& o){ i*=o.i;}
112   void operator/=(const Op& o){ i/=o.i;}
113   void operator%=(const Op& o){ i%=o.i;}
114   // the +,-,*,... are friends
115   // (just to make life harder)
116   friend Op operator+(const Op& a,const Op& b){return Op(a.i+b.i);}
117   friend Op operator-(const Op& a,const Op& b);
118   friend Op operator*(const Op& a,const Op& b){return Op(a.i*b.i);}
119   friend Op operator/(const Op& a,const Op& b){return Op(a.i/b.i);}
120   friend Op operator%(const Op& a,const Op& b){return Op(a.i%b.i);}
121
122   // unary operators
123   Op operator-() const {return Op(-i);}
124   bool operator !() const {return !(i);}
125
126   // overloading the [] operator
127   // need 2 versions: get & set
128   // note: C++ can be a little mixed up upon which version it calls
129   // most of the time it calls the second version
130   int operator[](unsigned idx)const
131   {       if (idx==0) return i; return 0;}
132   int& operator[](unsigned idx)
133   {       if (idx==0) return i; static int j;j=0; return j;}
134
135   // overloading the () operator
136   // this can have many parameters so we will test this
137   int operator()(int a=0){return i+a;}
138   int operator()(int a,int b){return i+a+b;}
139
140   // increment/decrement operators
141   Op& operator++() {++i; return *this;} // prefix ++
142   Op operator++(int) {Op o = *this; ++(*this); return o;} // postfix ++
143   Op& operator--() {--i; return *this;} // prefix --
144   Op operator--(int) {Op o = *this; --(*this); return o;} // postfix --
145
146   // TODO: <<,<<=
147
148   // cast operators
149   operator double() { return i; }
150   virtual operator int() { return i; }
151
152   // This method just checks that the operators are implemented correctly
153   static void sanity_check();
154 };
155
156 // just to complicate matters
157 // we have a couple of non class operators
158 inline bool operator==(const Op& a,const Op& b){return a.i==b.i;}
159 inline bool operator!=(const Op& a,const Op& b){return a.i!=b.i;}
160 inline bool operator< (const Op& a,const Op& b){return a.i<b.i;}
161 inline bool operator<=(const Op& a,const Op& b){return a.i<=b.i;}
162 inline bool operator> (const Op& a,const Op& b){return a.i>b.i;}
163 inline bool operator>=(const Op& a,const Op& b){return a.i>=b.i;}
164
165 %}
166
167 %{
168   // This one is not declared inline as VC++7.1 gets mixed up with the unary operator-
169   Op operator-(const Op& a,const Op& b){return Op(a.i-b.i);}
170 %}
171
172 // in order to wrapper this correctly
173 // we need to extend the class
174 // to make the friends & non members part of the class
175 %extend Op{
176         Op operator &&(const Op& b){return Op($self->i&&b.i);}
177         Op operator or(const Op& b){return Op($self->i||b.i);}
178
179         Op operator+(const Op& b){return Op($self->i+b.i);}
180         Op operator-(const Op& b){return Op($self->i-b.i);}
181         Op operator*(const Op& b){return Op($self->i*b.i);}
182         Op operator/(const Op& b){return Op($self->i/b.i);}
183         Op operator%(const Op& b){return Op($self->i%b.i);}
184
185         bool operator==(const Op& b){return $self->i==b.i;}
186         bool operator!=(const Op& b){return $self->i!=b.i;}
187         bool operator< (const Op& b){return $self->i<b.i;}
188         bool operator<=(const Op& b){return $self->i<=b.i;}
189         bool operator> (const Op& b){return $self->i>b.i;}
190         bool operator>=(const Op& b){return $self->i>=b.i;}
191
192         // subtraction with reversed arguments
193         Op __rsub__(const int b){return Op(b - $self->i);}
194
195         // we also add the __str__() fn to the class
196         // this allows it to be converted to a string (so it can be printed)
197         const char* __str__()
198         {
199                 static char buffer[255];
200                 sprintf(buffer,"Op(%d)",$self->i);
201                 return buffer;
202         }
203         // to get the [] operator working correctly we need to extend with two function
204         // __getitem__ & __setitem__
205         int __getitem__(unsigned i)
206         {       return (*$self)[i];     }
207         void __setitem__(unsigned i,int v)
208         {       (*$self)[i]=v;  }
209 }
210
211 /*
212 Suggested list of operator overloads (mainly from python)
213
214 Operators overloaded with their C++ equivalent
215 __add__,__sub__,__mul__,__div__,__mod__ +,-,*,/,%
216 __iadd__,__isub__,__imul__,__idiv__,__imod__    +=,-=,*=,/=,%=
217
218 __eq__,__ne__,__lt__,__le__,__gt__,__ge__ ==,!=,<,<=,>,>=
219 __not__,__neg__ unary !, unary -
220 __and__,__or__,__xor__  logical and,logical or,logical xor
221 __rshift__,__lshift__ >>,<<
222
223 __getitem__,__setitem__ for operator[]
224
225 Operators overloaded without C++ equivilents
226 __pow__ for power operator
227 __str__ converts object to a string (should return a const char*)
228 __concat__ for contatenation (if language supports)
229
230 */
231
232 %inline %{
233 class OpDerived : public Op {
234 public:
235   OpDerived(int a=0) : Op(a)
236   {}
237
238   // overloaded
239   virtual operator int() { return i*2; }
240 };
241 %}
242
243
244 %{
245
246 #include <assert.h>
247
248 void Op::sanity_check()
249 {
250         // test routine:
251         Op a;
252         Op b=5;
253         Op c=b; // copy construct
254         Op d=2;
255         Op dd=d; // assignment operator
256
257         // test equality
258         assert(a!=b);
259         assert(b==c);
260         assert(a!=d);
261         assert(d==dd);
262
263         // test <
264         assert(a<b);
265         assert(a<=b);
266         assert(b<=c);
267         assert(b>=c);
268         assert(b>d);
269         assert(b>=d);
270
271         // test +=
272         Op e=3;
273         e+=d;
274         assert(e==b);
275         e-=c;
276         assert(e==a);
277         e=Op(1);
278         e*=b;
279         assert(e==c);
280         e/=d;
281         assert(e==d);
282         e%=c;
283         assert(e==d);
284
285         // test +
286         Op f(1),g(1);
287         assert(f+g==Op(2));
288         assert(f-g==Op(0));
289         assert(f*g==Op(1));
290         assert(f/g==Op(1));
291         assert(f%g==Op(0));
292
293         // test unary operators
294         assert(!a==true);
295         assert(!b==false);
296         assert(-a==a);
297         assert(-b==Op(-5));
298
299         // test []
300         Op h=3;
301         assert(h[0]==3);
302         assert(h[1]==0);
303         h[0]=2; // set
304         assert(h[0]==2);
305         h[1]=2; // ignored
306         assert(h[0]==2);
307         assert(h[1]==0);
308
309         // test ()
310         Op i=3;
311         assert(i()==3);
312         assert(i(1)==4);
313         assert(i(1,2)==6);
314
315         // plus add some code to check the __str__ fn
316         //assert(str(Op(1))=="Op(1)");
317         //assert(str(Op(-3))=="Op(-3)");
318
319         // test ++ and --
320         Op j(100);
321         int original = j.i;
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           Op newOp = --j;
342           int newInt = --original;
343           assert(j.i == original);
344           assert(newOp.i == newInt);
345         }
346
347         // cast operators
348         Op k=3;
349         int check_k = k;
350         assert (check_k == 3);
351
352         Op l=4;
353         double check_l = l;
354         assert (check_l == 4);
355 }
356
357 %}
358