PageRenderTime 63ms CodeModel.GetById 21ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/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