diff --git a/SWIG/Doc/Manual/Lua.html b/SWIG/Doc/Manual/Lua.html index 87a03d760..d3a9b7647 100644 --- a/SWIG/Doc/Manual/Lua.html +++ b/SWIG/Doc/Manual/Lua.html @@ -824,11 +824,11 @@ Now we extend it with some new code
%extend Complex {
const char *__str__() {
static char tmp[1024];
- sprintf(tmp,"Complex(%g,%g)", self->re(),self->im());
+ sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im());
return tmp;
}
bool operator==(const Complex& c)
- { return (self->re()==c.re() && self->im()==c.im();}
+ { return ($self->re()==c.re() && $self->im()==c.im();}
};
@@ -846,7 +846,7 @@ true true
-Extend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the 'self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class). +Extend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the '$self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class).
class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
%extend MyArray {
// MyArray#size is an alias for MyArray#length
size_t size() const {
return self->length();
}
}
+ class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
%extend MyArray {
// MyArray#size is an alias for MyArray#length
size_t size() const {
return $self->length();
}
}
A better solution is to use the %alias directive (unique to diff --git a/SWIG/Doc/Manual/SWIG.html b/SWIG/Doc/Manual/SWIG.html index 8186f9e13..d13c56bc1 100644 --- a/SWIG/Doc/Manual/SWIG.html +++ b/SWIG/Doc/Manual/SWIG.html @@ -2356,18 +2356,23 @@ You can make a Vector look a lot like a class by writing a SWIG interfa return v; } ~Vector() { - free(self); + free($self); } double magnitude() { - return sqrt(self->x*self->x+self->y*self->y+self->z*self->z); + return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z); } void print() { - printf("Vector [%g, %g, %g]\n", self->x,self->y,self->z); + printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z); } }; +
+Note the usage of the $self special variable. +Its usage is identical to a C++ 'this' pointer and should be used whenever access to the struct instance is required. +
+Now, when used with proxy classes in Python, you can do things like this :
diff --git a/SWIG/Doc/Manual/SWIGPlus.html b/SWIG/Doc/Manual/SWIGPlus.html index 3ec61f639..c4aa28f0d 100644 --- a/SWIG/Doc/Manual/SWIGPlus.html +++ b/SWIG/Doc/Manual/SWIGPlus.html @@ -2734,7 +2734,7 @@ public: %extend { char *__str__() { static char temp[256]; - sprintf(temp,"[ %g, %g, %g ]", self->x,self->y,self->z); + sprintf(temp,"[ %g, %g, %g ]", $self->x,$self->y,$self->z); return &temp[0]; } } @@ -2760,10 +2760,37 @@ command. ++The C++ 'this' pointer is often needed to access member variables, methods etc. +The $self special variable should be used wherever you could use 'this'. +The example above demonstrates this for accessing member variables. +The implicit 'this' pointer that is present in C++ methods is not present in %extend methods. +In order to access anything in the extended class or its base class, an explicit 'this' is required. +The following example shows how one could access base class members: +
+ +
+struct Base {
+ virtual void method(int v) {
+ ...
+ }
+ int value;
+};
+struct Derived : Base {
+};
+%extend Derived {
+ virtual void method(int v) {
+ $self->Base::method(v);
+ $self->value = v;
+ ...
+ }
+}
+The %extend directive follows all of the same conventions -as its use with C structures. Please refer to the SWIG Basics -chapter for further details. +as its use with C structures. Please refer to the Adding member functions to C structures +section for further details.
@@ -3446,7 +3473,7 @@ It is also possible to separate these declarations from the template class. For } /* Make a copy */ T *__copy__() { - return new List<T>(*self); + return new List<T>(*$self); } }; diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index 88743f856..ec6b1b044 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -1276,7 +1276,7 @@ int Language::staticmemberfunctionHandler(Node *n) { if (!defaultargs && code) { /* Hmmm. An added static member. We have to create a little wrapper for this */ - Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus); + Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0); } } diff --git a/SWIG/Source/Swig/cwrap.c b/SWIG/Source/Swig/cwrap.c index 69f22e024..cccf0dab0 100644 --- a/SWIG/Source/Swig/cwrap.c +++ b/SWIG/Source/Swig/cwrap.c @@ -737,19 +737,21 @@ String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_ } /* ----------------------------------------------------------------------------- - * Swig_extension_code() + * extension_code() * * Generates an extension function (a function defined in %extend) * * return_type function_name(parms) code * * ----------------------------------------------------------------------------- */ -String *Swig_extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus) { +static String *extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms); String *sig = NewStringf("%s(%s)", function_name, parms_str); String *rt_sig = SwigType_str(return_type, sig); String *body = NewStringf("SWIGINTERN %s", rt_sig); Printv(body, code, "\n", NIL); + if (self) + Replaceall(body, "$self", self); Delete(parms_str); Delete(sig); Delete(rt_sig); @@ -762,11 +764,11 @@ String *Swig_extension_code(const String *function_name, ParmList *parms, SwigTy * Generates an extension function (a function defined in %extend) and * adds it to the "wrap:code" attribute of a node * - * See also Swig_extension_code() + * See also extension_code() * * ----------------------------------------------------------------------------- */ -int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus) { - String *body = Swig_extension_code(function_name, parms, return_type, code, cplusplus); +int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { + String *body = extension_code(function_name, parms, return_type, code, cplusplus, self); Setattr(n, k_wrapcode, body); Delete(body); return SWIG_OK; @@ -790,8 +792,8 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); } - /* If node is a member template expansion, we don't allow added code */ + /* If node is a member template expansion, we don't allow added code */ if (Getattr(n, k_templatetype)) flags &= ~(CWRAP_EXTEND); @@ -908,8 +910,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc /* See if there is any code that we need to emit */ if (!defaultargs && code && !is_smart_pointer) { - Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus); - + Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, k_self); } if (is_smart_pointer) { int i = 0; @@ -1057,7 +1058,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis /* See if there is any code that we need to emit */ if (!defaultargs && code) { - Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus); + Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus, k_self); } call = Swig_cfunction_call(mangled, parms); @@ -1170,7 +1171,7 @@ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) mangled = Swig_name_mangle(membername); code = Getattr(n, k_code); if (code) { - Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus); + Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, k_self); } call = Swig_cfunction_call(mangled, p); cres = NewStringf("%s;\n", call); @@ -1256,7 +1257,7 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { String *cres; String *code = Getattr(n, k_code); if (code) { - Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus); + Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, k_self); } call = Swig_cfunction_call(mangled, parms); cres = NewStringf("%s;\n", call); @@ -1332,7 +1333,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { String *code = Getattr(n, k_code); if (code) { - Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus); + Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, k_self); } call = Swig_cfunction_call(mangled, parms); cres = Swig_cresult(ty, k_result, call); diff --git a/SWIG/Source/Swig/swig.h b/SWIG/Source/Swig/swig.h index d6ab58c0e..426906c47 100644 --- a/SWIG/Source/Swig/swig.h +++ b/SWIG/Source/Swig/swig.h @@ -489,8 +489,7 @@ extern "C" { extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self, int varcref); extern String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self, int varcref); - extern String *Swig_extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus); - extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus); + extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self); /* --- Transformations --- */