PageRenderTime 62ms CodeModel.GetById 50ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Examples/test-suite/operator_overload.i

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