PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

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