PageRenderTime 17ms CodeModel.GetById 9ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/python/pyopers.swg

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