fix inplace python opers
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5859 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
be31340148
commit
fd1c9fb316
2 changed files with 82 additions and 10 deletions
|
|
@ -18,16 +18,6 @@
|
|||
%rename(__or__) *::operator|;
|
||||
%rename(__xor__) *::operator^;
|
||||
%rename(__invert__) *::operator~;
|
||||
%rename(__iadd__) *::operator+=;
|
||||
%rename(__isub__) *::operator-=;
|
||||
%rename(__imul__) *::operator*=;
|
||||
%rename(__idiv__) *::operator/=;
|
||||
%rename(__imod__) *::operator%=;
|
||||
%rename(__ilshift__) *::operator<<=;
|
||||
%rename(__irshift__) *::operator>>=;
|
||||
%rename(__iand__) *::operator&=;
|
||||
%rename(__ior__) *::operator|=;
|
||||
%rename(__ixor__) *::operator^=;
|
||||
%rename(__lt__) *::operator<;
|
||||
%rename(__le__) *::operator<=;
|
||||
%rename(__gt__) *::operator>;
|
||||
|
|
@ -48,4 +38,60 @@
|
|||
%ignorewarn("386:operator->* ignored") operator->*;
|
||||
%ignorewarn("389:operator[] ignored (consider using %extend)") operator[];
|
||||
|
||||
/*
|
||||
Inplace operator declarations.
|
||||
|
||||
They translate the inplace C++ operators (+=, -=, ...) into the
|
||||
corresponding python equivalents(__iadd__,__isub__), etc,
|
||||
disabling the ownership of the input 'self' pointer, and assigning
|
||||
it to the returning object:
|
||||
|
||||
%feature("self:disown") *::Operator;
|
||||
%feature("new") *::Operator;
|
||||
|
||||
This makes the most common case safe, ie:
|
||||
|
||||
A& A::operator+=(int i) { ...; return *this; }
|
||||
^^^^ ^^^^^^
|
||||
|
||||
will work fine, even when the resulting python object shares the
|
||||
'this' pointer with the input one. The input object is usually
|
||||
deleted after the operation, including the shared 'this' pointer,
|
||||
producing 'strange' seg faults, as reported by Lucriz
|
||||
(lucriz@sitilandia.it).
|
||||
|
||||
If you have an interface that already takes care of that, ie, you
|
||||
already are using inplace operators and you are not getting
|
||||
seg. faults, with the new scheme you could end with 'free' elements
|
||||
that never get deleted (maybe, not sure, it depends). But if that is
|
||||
the case, you could recover the old behaviour using
|
||||
|
||||
%feature("self:disown","") A::operator+=;
|
||||
%feature("new","") A::operator+=;
|
||||
|
||||
which recovers the old behaviour for the class 'A', or if you are
|
||||
100% sure your entire system works fine in the old way, use:
|
||||
|
||||
%feature("self:disown","") *::operator+=;
|
||||
%feature("new","") *::operator+=;
|
||||
|
||||
*/
|
||||
|
||||
%define %swig_inplace_oper(Oper, PyOper)
|
||||
%feature("self:disown") *::Oper;
|
||||
%feature("new") *::Oper;
|
||||
%rename(__##PyOper##__) *::Oper;
|
||||
%enddef
|
||||
|
||||
%swig_inplace_oper(operator +=, iadd);
|
||||
%swig_inplace_oper(operator -=, isub);
|
||||
%swig_inplace_oper(operator *=, imul);
|
||||
%swig_inplace_oper(operator /=, idiv);
|
||||
%swig_inplace_oper(operator %=, imod);
|
||||
%swig_inplace_oper(operator &=, iand);
|
||||
%swig_inplace_oper(operator |=, ior);
|
||||
%swig_inplace_oper(operator ^=, ixor);
|
||||
%swig_inplace_oper(operator <<=, ilshift);
|
||||
%swig_inplace_oper(operator >>=, irshift);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue