/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
- /* File : operator_overload.i */
- /*
- This is a test of all the possible operator overloads
- see bottom for a set of possible tests
- */
- %module operator_overload
- #if defined(SWIGPYTHON)
- %warnfilter(SWIGWARN_IGNORE_OPERATOR_EQ,
- SWIGWARN_IGNORE_OPERATOR_INDEX,
- SWIGWARN_IGNORE_OPERATOR_PLUSPLUS,
- SWIGWARN_IGNORE_OPERATOR_MINUSMINUS,
- SWIGWARN_IGNORE_OPERATOR_LAND,
- SWIGWARN_IGNORE_OPERATOR_LOR);
- #endif
- #if !defined(SWIGLUA) && !defined(SWIGR)
- %rename(Equal) operator =;
- %rename(PlusEqual) operator +=;
- %rename(MinusEqual) operator -=;
- %rename(MultiplyEqual) operator *=;
- %rename(DivideEqual) operator /=;
- %rename(PercentEqual) operator %=;
- %rename(Plus) operator +;
- %rename(Minus) operator -;
- %rename(Multiply) operator *;
- %rename(Divide) operator /;
- %rename(Percent) operator %;
- %rename(Not) operator !;
- %rename(IndexIntoConst) operator[](unsigned idx) const;
- %rename(IndexInto) operator[](unsigned idx);
- %rename(Functor) operator ();
- %rename(EqualEqual) operator ==;
- %rename(NotEqual) operator !=;
- %rename(LessThan) operator <;
- %rename(LessThanEqual) operator <=;
- %rename(GreaterThan) operator >;
- %rename(GreaterThanEqual) operator >=;
- %rename(And) operator &&;
- %rename(Or) operator ||;
- %rename(PlusPlusPrefix) operator++();
- %rename(PlusPlusPostfix) operator++(int);
- %rename(MinusMinusPrefix) operator--();
- %rename(MinusMinusPostfix) operator--(int);
- #endif
- #ifdef SWIGCSHARP
- %csmethodmodifiers operator++() "protected";
- %csmethodmodifiers operator++(int) "private";
- %csmethodmodifiers operator--() "private";
- %csmethodmodifiers operator--(int) "protected";
- %typemap(cscode) Op %{
- public static Op operator++(Op op) {
- // Unlike C++, operator++ must not modify the parameter and both prefix and postfix operations call this method
- Op newOp = new Op(op.i);
- newOp.PlusPlusPostfix(0);
- return newOp;
- }
- public static Op operator--(Op op) {
- // Unlike C++, operator-- must not modify the parameter and both prefix and postfix operations call this method
- Op newOp = new Op(op.i);
- newOp.MinusMinusPrefix();
- return newOp;
- }
- %}
- #endif
- #ifdef SWIGPHP
- %rename(AndOperator) operator &&;
- %rename(OrOperator) operator ||;
- #endif
- %rename(IntCast) operator int();
- %rename(DoubleCast) operator double();
- %inline %{
- #if defined(_MSC_VER)
- #include <iso646.h> /* for named logical operator, eg 'operator or' */
- #endif
- #include <assert.h>
- class Op {
- public:
- int i;
- Op(int a=0) : i(a)
- {}
- Op(const Op& o) : i(o.i)
- {}
- virtual ~Op()
- {}
- friend Op operator &&(const Op& a,const Op& b){return Op(a.i&&b.i);}
- friend Op operator or(const Op& a,const Op& b){return Op(a.i||b.i);}
- Op &operator=(const Op& o) {
- i=o.i;
- return *this;
- }
- // +=,-=... are member fns
- void operator+=(const Op& o){ i+=o.i;}
- void operator-=(const Op& o){ i-=o.i;}
- void operator*=(const Op& o){ i*=o.i;}
- void operator/=(const Op& o){ i/=o.i;}
- void operator%=(const Op& o){ i%=o.i;}
- // the +,-,*,... are friends
- // (just to make life harder)
- friend Op operator+(const Op& a,const Op& b){return Op(a.i+b.i);}
- friend Op operator-(const Op& a,const Op& b);
- friend Op operator*(const Op& a,const Op& b){return Op(a.i*b.i);}
- friend Op operator/(const Op& a,const Op& b){return Op(a.i/b.i);}
- friend Op operator%(const Op& a,const Op& b){return Op(a.i%b.i);}
- // unary operators
- Op operator-() const {return Op(-i);}
- bool operator !() const {return !(i);}
- // overloading the [] operator
- // need 2 versions: get & set
- // note: C++ can be a little mixed up upon which version it calls
- // most of the time it calls the second version
- int operator[](unsigned idx)const
- { if (idx==0) return i; return 0;}
- int& operator[](unsigned idx)
- { if (idx==0) return i; static int j;j=0; return j;}
- // overloading the () operator
- // this can have many parameters so we will test this
- int operator()(int a=0){return i+a;}
- int operator()(int a,int b){return i+a+b;}
- // increment/decrement operators
- Op& operator++() {++i; return *this;} // prefix ++
- Op operator++(int) {Op o = *this; ++(*this); return o;} // postfix ++
- Op& operator--() {--i; return *this;} // prefix --
- Op operator--(int) {Op o = *this; --(*this); return o;} // postfix --
- // TODO: <<,<<=
- // cast operators
- operator double() { return i; }
- virtual operator int() { return i; }
- // This method just checks that the operators are implemented correctly
- static void sanity_check();
- };
- // just to complicate matters
- // we have a couple of non class operators
- inline bool operator==(const Op& a,const Op& b){return a.i==b.i;}
- inline bool operator!=(const Op& a,const Op& b){return a.i!=b.i;}
- inline bool operator< (const Op& a,const Op& b){return a.i<b.i;}
- inline bool operator<=(const Op& a,const Op& b){return a.i<=b.i;}
- inline bool operator> (const Op& a,const Op& b){return a.i>b.i;}
- inline bool operator>=(const Op& a,const Op& b){return a.i>=b.i;}
- %}
- %{
- // This one is not declared inline as VC++7.1 gets mixed up with the unary operator-
- Op operator-(const Op& a,const Op& b){return Op(a.i-b.i);}
- %}
- // in order to wrapper this correctly
- // we need to extend the class
- // to make the friends & non members part of the class
- %extend Op{
- Op operator &&(const Op& b){return Op($self->i&&b.i);}
- Op operator or(const Op& b){return Op($self->i||b.i);}
- Op operator+(const Op& b){return Op($self->i+b.i);}
- Op operator-(const Op& b){return Op($self->i-b.i);}
- Op operator*(const Op& b){return Op($self->i*b.i);}
- Op operator/(const Op& b){return Op($self->i/b.i);}
- Op operator%(const Op& b){return Op($self->i%b.i);}
- bool operator==(const Op& b){return $self->i==b.i;}
- bool operator!=(const Op& b){return $self->i!=b.i;}
- bool operator< (const Op& b){return $self->i<b.i;}
- bool operator<=(const Op& b){return $self->i<=b.i;}
- bool operator> (const Op& b){return $self->i>b.i;}
- bool operator>=(const Op& b){return $self->i>=b.i;}
- // subtraction with reversed arguments
- Op __rsub__(const int b){return Op(b - $self->i);}
- // we also add the __str__() fn to the class
- // this allows it to be converted to a string (so it can be printed)
- const char* __str__()
- {
- static char buffer[255];
- sprintf(buffer,"Op(%d)",$self->i);
- return buffer;
- }
- // to get the [] operator working correctly we need to extend with two function
- // __getitem__ & __setitem__
- int __getitem__(unsigned i)
- { return (*$self)[i]; }
- void __setitem__(unsigned i,int v)
- { (*$self)[i]=v; }
- }
- /*
- Suggested list of operator overloads (mainly from python)
- Operators overloaded with their C++ equivalent
- __add__,__sub__,__mul__,__div__,__mod__ +,-,*,/,%
- __iadd__,__isub__,__imul__,__idiv__,__imod__ +=,-=,*=,/=,%=
- __eq__,__ne__,__lt__,__le__,__gt__,__ge__ ==,!=,<,<=,>,>=
- __not__,__neg__ unary !, unary -
- __and__,__or__,__xor__ logical and,logical or,logical xor
- __rshift__,__lshift__ >>,<<
- __getitem__,__setitem__ for operator[]
- Operators overloaded without C++ equivilents
- __pow__ for power operator
- __str__ converts object to a string (should return a const char*)
- __concat__ for contatenation (if language supports)
- */
- %inline %{
- class OpDerived : public Op {
- public:
- OpDerived(int a=0) : Op(a)
- {}
- // overloaded
- virtual operator int() { return i*2; }
- };
- %}
- %{
- #include <assert.h>
- void Op::sanity_check()
- {
- // test routine:
- Op a;
- Op b=5;
- Op c=b; // copy construct
- Op d=2;
- Op dd=d; // assignment operator
- // test equality
- assert(a!=b);
- assert(b==c);
- assert(a!=d);
- assert(d==dd);
- // test <
- assert(a<b);
- assert(a<=b);
- assert(b<=c);
- assert(b>=c);
- assert(b>d);
- assert(b>=d);
- // test +=
- Op e=3;
- e+=d;
- assert(e==b);
- e-=c;
- assert(e==a);
- e=Op(1);
- e*=b;
- assert(e==c);
- e/=d;
- assert(e==d);
- e%=c;
- assert(e==d);
- // test +
- Op f(1),g(1);
- assert(f+g==Op(2));
- assert(f-g==Op(0));
- assert(f*g==Op(1));
- assert(f/g==Op(1));
- assert(f%g==Op(0));
- // test unary operators
- assert(!a==true);
- assert(!b==false);
- assert(-a==a);
- assert(-b==Op(-5));
- // test []
- Op h=3;
- assert(h[0]==3);
- assert(h[1]==0);
- h[0]=2; // set
- assert(h[0]==2);
- h[1]=2; // ignored
- assert(h[0]==2);
- assert(h[1]==0);
- // test ()
- Op i=3;
- assert(i()==3);
- assert(i(1)==4);
- assert(i(1,2)==6);
- // plus add some code to check the __str__ fn
- //assert(str(Op(1))=="Op(1)");
- //assert(str(Op(-3))=="Op(-3)");
- // test ++ and --
- Op j(100);
- int original = j.i;
- {
- Op newOp = j++;
- int newInt = original++;
- assert(j.i == original);
- assert(newOp.i == newInt);
- }
- {
- Op newOp = j--;
- int newInt = original--;
- assert(j.i == original);
- assert(newOp.i == newInt);
- }
- {
- Op newOp = ++j;
- int newInt = ++original;
- assert(j.i == original);
- assert(newOp.i == newInt);
- }
- {
- Op newOp = --j;
- int newInt = --original;
- assert(j.i == original);
- assert(newOp.i == newInt);
- }
- // cast operators
- Op k=3;
- int check_k = k;
- assert (check_k == 3);
- Op l=4;
- double check_l = l;
- assert (check_l == 4);
- }
- %}