PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Lib/python/pyopers.swg

#
Unknown | 235 lines | 182 code | 53 blank | 0 comment | 0 complexity | 6f48f3d251b57cac483faf2787d5f9bd MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* ------------------------------------------------------------
  2. * Overloaded operator support
  3. The directives in this file apply whether or not you use the
  4. -builtin option to SWIG, but operator overloads are particularly
  5. attractive when using -builtin, because they are much faster
  6. than named methods.
  7. If you're using the -builtin option to SWIG, and you want to define
  8. python operator overloads beyond the defaults defined in this file,
  9. here's what you need to know:
  10. There are two ways to define a python slot function: dispatch to a
  11. statically defined function; or dispatch to a method defined on the
  12. operand.
  13. To dispatch to a statically defined function, use %feature("python:<slot>"),
  14. where <slot> is the name of a field in a PyTypeObject, PyNumberMethods,
  15. PyMappingMethods, PySequenceMethods, or PyBufferProcs. For example:
  16. %{
  17. static long myHashFunc (PyObject *pyobj) {
  18. MyClass *cobj;
  19. // Convert pyobj to cobj
  20. return (cobj->field1 * (cobj->field2 << 7));
  21. }
  22. %}
  23. %feature("python:tp_hash") MyClass "myHashFunc";
  24. NOTE: It is the responsibility of the programmer (that's you) to ensure
  25. that a statically defined slot function has the correct signature.
  26. If, instead, you want to dispatch to an instance method, you can
  27. use %feature("python:slot"). For example:
  28. class MyClass {
  29. public:
  30. long myHashFunc () const;
  31. ...
  32. };
  33. %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
  34. NOTE: Some python slots use a method signature which does not
  35. match the signature of SWIG-wrapped methods. For those slots,
  36. SWIG will automatically generate a "closure" function to re-marshall
  37. the arguments before dispatching to the wrapped method. Setting
  38. the "functype" attribute of the feature enables SWIG to generate
  39. a correct closure function.
  40. --------------------------------------------------------------
  41. The tp_richcompare slot is a special case: SWIG automatically generates
  42. a rich compare function for all wrapped types. If a type defines C++
  43. operator overloads for comparison (operator==, operator<, etc.), they
  44. will be called from the generated rich compare function. If you
  45. want to explicitly choose a method to handle a certain comparison
  46. operation, you may use %feature("python:slot") like this:
  47. class MyClass {
  48. public:
  49. bool lessThan (const MyClass& x) const;
  50. ...
  51. };
  52. %feature("python:slot", "Py_LT") MyClass::lessThan;
  53. ... where "Py_LT" is one of the rich comparison opcodes defined in the
  54. python header file object.h.
  55. If there's no method defined to handle a particular comparsion operation,
  56. the default behavior is to compare pointer values of the wrapped
  57. C++ objects.
  58. --------------------------------------------------------------
  59. For more information about python slots, including their names and
  60. signatures, you may refer to the python documentation :
  61. http://docs.python.org/c-api/typeobj.html
  62. * ------------------------------------------------------------ */
  63. #ifdef __cplusplus
  64. #if defined(SWIGPYTHON_BUILTIN)
  65. #define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:slot", #slt, functype=#functp) oper; %feature("python:slot", #slt, functype=#functp) pyname;
  66. #define %pycompare(pyname,oper,comptype) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:compare", #comptype) oper; %feature("python:compare", #comptype) pyname;
  67. #else
  68. #define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper
  69. #define %pycompare(pyname,oper,comptype) %pybinoperator(pyname,oper,,comptype)
  70. #endif
  71. %pybinoperator(__add__, *::operator+, binaryfunc, nb_add);
  72. %pybinoperator(__pos__, *::operator+(), unaryfunc, nb_positive);
  73. %pybinoperator(__pos__, *::operator+() const, unaryfunc, nb_positive);
  74. %pybinoperator(__sub__, *::operator-, binaryfunc, nb_subtract);
  75. %pybinoperator(__neg__, *::operator-(), unaryfunc, nb_negative);
  76. %pybinoperator(__neg__, *::operator-() const, unaryfunc, nb_negative);
  77. %pybinoperator(__mul__, *::operator*, binaryfunc, nb_multiply);
  78. %pybinoperator(__div__, *::operator/, binaryfunc, nb_div);
  79. %pybinoperator(__mod__, *::operator%, binaryfunc, nb_remainder);
  80. %pybinoperator(__lshift__, *::operator<<, binaryfunc, nb_lshift);
  81. %pybinoperator(__rshift__, *::operator>>, binaryfunc, nb_rshift);
  82. %pybinoperator(__and__, *::operator&, binaryfunc, nb_and);
  83. %pybinoperator(__or__, *::operator|, binaryfunc, nb_or);
  84. %pybinoperator(__xor__, *::operator^, binaryfunc, nb_xor);
  85. %pycompare(__lt__, *::operator<, Py_LT);
  86. %pycompare(__le__, *::operator<=, Py_LE);
  87. %pycompare(__gt__, *::operator>, Py_GT);
  88. %pycompare(__ge__, *::operator>=, Py_GE);
  89. %pycompare(__eq__, *::operator==, Py_EQ);
  90. %pycompare(__ne__, *::operator!=, Py_NE);
  91. %feature("python:slot", "nb_truediv", functype="binaryfunc") *::operator/;
  92. /* Special cases */
  93. %rename(__invert__) *::operator~;
  94. %feature("python:slot", "nb_invert", functype="unaryfunc") *::operator~;
  95. %rename(__call__) *::operator();
  96. %feature("python:slot", "tp_call", functype="ternarycallfunc") *::operator();
  97. #if defined(SWIGPYTHON_BUILTIN)
  98. %pybinoperator(__nonzero__, *::operator bool, inquiry, nb_nonzero);
  99. #else
  100. %feature("shadow") *::operator bool %{
  101. def __nonzero__(self):
  102. return $action(self)
  103. __bool__ = __nonzero__
  104. %};
  105. %rename(__nonzero__) *::operator bool;
  106. #endif
  107. /* Ignored operators */
  108. %ignoreoperator(LNOT) operator!;
  109. %ignoreoperator(LAND) operator&&;
  110. %ignoreoperator(LOR) operator||;
  111. %ignoreoperator(EQ) *::operator=;
  112. %ignoreoperator(PLUSPLUS) *::operator++;
  113. %ignoreoperator(MINUSMINUS) *::operator--;
  114. %ignoreoperator(ARROWSTAR) *::operator->*;
  115. %ignoreoperator(INDEX) *::operator[];
  116. /*
  117. Inplace operator declarations.
  118. They translate the inplace C++ operators (+=, -=, ...) into the
  119. corresponding python equivalents(__iadd__,__isub__), etc,
  120. disabling the ownership of the input 'self' pointer, and assigning
  121. it to the returning object:
  122. %feature("del") *::Operator;
  123. %feature("new") *::Operator;
  124. This makes the most common case safe, ie:
  125. A& A::operator+=(int i) { ...; return *this; }
  126. ^^^^ ^^^^^^
  127. will work fine, even when the resulting python object shares the
  128. 'this' pointer with the input one. The input object is usually
  129. deleted after the operation, including the shared 'this' pointer,
  130. producing 'strange' seg faults, as reported by Lucriz
  131. (lucriz@sitilandia.it).
  132. If you have an interface that already takes care of that, ie, you
  133. already are using inplace operators and you are not getting
  134. seg. faults, with the new scheme you could end with 'free' elements
  135. that never get deleted (maybe, not sure, it depends). But if that is
  136. the case, you could recover the old behaviour using
  137. %feature("del","") A::operator+=;
  138. %feature("new","") A::operator+=;
  139. which recovers the old behaviour for the class 'A', or if you are
  140. 100% sure your entire system works fine in the old way, use:
  141. %feature("del","") *::operator+=;
  142. %feature("new","") *::operator+=;
  143. */
  144. #if defined(SWIGPYTHON_BUILTIN)
  145. #define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %feature("python:slot", #slt, functype=#functp) Oper; %rename(SwigPyOper) Oper
  146. #else
  147. #define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %rename(SwigPyOper) Oper
  148. #endif
  149. %pyinplaceoper(__iadd__ , *::operator +=, binaryfunc, nb_inplace_add);
  150. %pyinplaceoper(__isub__ , *::operator -=, binaryfunc, nb_inplace_subtract);
  151. %pyinplaceoper(__imul__ , *::operator *=, binaryfunc, nb_inplace_multiply);
  152. %pyinplaceoper(__idiv__ , *::operator /=, binaryfunc, nb_inplace_divide);
  153. %pyinplaceoper(__imod__ , *::operator %=, binaryfunc, nb_inplace_remainder);
  154. %pyinplaceoper(__iand__ , *::operator &=, binaryfunc, nb_inplace_and);
  155. %pyinplaceoper(__ior__ , *::operator |=, binaryfunc, nb_inplace_or);
  156. %pyinplaceoper(__ixor__ , *::operator ^=, binaryfunc, nb_inplace_xor);
  157. %pyinplaceoper(__ilshift__, *::operator <<=, binaryfunc, nb_inplace_lshift);
  158. %pyinplaceoper(__irshift__, *::operator >>=, binaryfunc, nb_inplace_rshift);
  159. /* Finally, in python we need to mark the binary operations to fail as
  160. 'maybecall' methods */
  161. #define %pybinopermaybecall(oper) %pythonmaybecall __ ## oper ## __; %pythonmaybecall __r ## oper ## __
  162. %pybinopermaybecall(add);
  163. %pybinopermaybecall(pos);
  164. %pybinopermaybecall(pos);
  165. %pybinopermaybecall(sub);
  166. %pybinopermaybecall(neg);
  167. %pybinopermaybecall(neg);
  168. %pybinopermaybecall(mul);
  169. %pybinopermaybecall(div);
  170. %pybinopermaybecall(mod);
  171. %pybinopermaybecall(lshift);
  172. %pybinopermaybecall(rshift);
  173. %pybinopermaybecall(and);
  174. %pybinopermaybecall(or);
  175. %pybinopermaybecall(xor);
  176. %pybinopermaybecall(lt);
  177. %pybinopermaybecall(le);
  178. %pybinopermaybecall(gt);
  179. %pybinopermaybecall(ge);
  180. %pybinopermaybecall(eq);
  181. %pybinopermaybecall(ne);
  182. #endif