ix variable wrapping with private assign operator + fix SwigValueWrapper
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6442 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
2e9ba807e8
commit
01bde715f4
2 changed files with 51 additions and 86 deletions
|
|
@ -321,74 +321,18 @@ static Parm *nonvoid_parms(Parm *p) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a hack.
|
/* -----------------------------------------------------------------------------
|
||||||
* Note that SwigValueWrapper should only be generated for value types which are classes and
|
* cplus_value_type()
|
||||||
* the class does not have a default constructor. It is also used for templated classes
|
|
||||||
* which havn't been passed to SWIG for parsing in case the class does not have a default
|
|
||||||
* constructor. Tip (SWIG-1.3.22 as of writing): Get SWIG to parse your templated class and
|
|
||||||
* use the %template directive (unnamed or not) to help SWIG decide whether or not
|
|
||||||
* SwigValueWrapper should be used, for example
|
|
||||||
* %template() std::auto_ptr<int>; // unnamed %template does not generate any proxy classes
|
|
||||||
*
|
*
|
||||||
* Upate: We turn the logic back,
|
* Returns the alternative value type needed in C++ for class value
|
||||||
* now we don't use the wrapper only when:
|
* types. When swig is not sure about using a plain $ltype value,
|
||||||
* 1.- We are not in CPlusPlus, ie, is C code
|
* since the class doesn't have a default constructor, or it can't be
|
||||||
* 2.- Is not a user type, ie, is int,short, ....
|
* assigned, you will get back 'SwigValueWrapper<type >'.
|
||||||
* 3.- Is a class, but we are sure that has a default constructor.
|
|
||||||
*
|
*
|
||||||
* any other case means we have no idea about what is going on, so,
|
* ----------------------------------------------------------------------------- */
|
||||||
* we play safe and weuse the wrapper.
|
|
||||||
*
|
|
||||||
* Now there are two ways to know if there is a default_constructor:
|
|
||||||
* 1.- swig detects it and set allocate:default_constructor
|
|
||||||
* 2.- the user specify it by using %feature("novaluewrapper"),
|
|
||||||
* just for the very ugly corner cases of opaque types, in that
|
|
||||||
* case the user need to type
|
|
||||||
*
|
|
||||||
* class MyOpaqueClass;
|
|
||||||
* %feature("novaluewrapper") MyOpaqueClass;
|
|
||||||
*/
|
|
||||||
SwigType *cplus_value_type(SwigType *t) {
|
|
||||||
Node *n = 0;
|
|
||||||
SwigType *w = 0;
|
|
||||||
int use_wrapper = 1;
|
|
||||||
if (CPlusPlus) {
|
|
||||||
SwigType *ftd = SwigType_typedef_resolve_all(t);
|
|
||||||
SwigType *td = SwigType_strip_qualifiers(ftd);
|
|
||||||
if (SwigType_type(td) == T_USER) {
|
|
||||||
if ((n = Swig_symbol_clookup(td,0))) {
|
|
||||||
if (((Strcmp(nodeType(n),"class") == 0)
|
|
||||||
&& !Getattr(n,"allocate:noassign")
|
|
||||||
&& (Getattr(n,"allocate:default_constructor")))
|
|
||||||
|| (Getattr(n,"feature:novaluewrapper"))) {
|
|
||||||
use_wrapper = Getattr(n,"feature:valuewrapper") ? 1 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
use_wrapper = 0;
|
|
||||||
}
|
|
||||||
if (use_wrapper) {
|
|
||||||
String *name = SwigType_str(t,0);
|
|
||||||
w = NewStringf("SwigValueWrapper< %s >",name);
|
|
||||||
Delete(name);
|
|
||||||
}
|
|
||||||
Delete(ftd);
|
|
||||||
Delete(td);
|
|
||||||
}
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Patch C++ pass-by-value */
|
SwigType *cplus_value_type(SwigType *t) {
|
||||||
void Language::patch_parms(Parm *p) {
|
return SwigType_alttype(t, 0);
|
||||||
while (p) {
|
|
||||||
SwigType *t = Getattr(p,"type");
|
|
||||||
SwigType *s = cplus_value_type(t);
|
|
||||||
if (s) {
|
|
||||||
Setattr(p,"alttype",s);
|
|
||||||
Delete(s);
|
|
||||||
}
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *first_nontemplate(Node *n) {
|
static Node *first_nontemplate(Node *n) {
|
||||||
|
|
@ -943,7 +887,6 @@ int
|
||||||
Language::functionHandler(Node *n) {
|
Language::functionHandler(Node *n) {
|
||||||
Parm *p;
|
Parm *p;
|
||||||
p = Getattr(n,"parms");
|
p = Getattr(n,"parms");
|
||||||
if (CPlusPlus) patch_parms(p);
|
|
||||||
if (!CurrentClass) {
|
if (!CurrentClass) {
|
||||||
globalfunctionHandler(n);
|
globalfunctionHandler(n);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1250,7 +1193,9 @@ Language::membervariableHandler(Node *n) {
|
||||||
|
|
||||||
/* Create a function to set the value of the variable */
|
/* Create a function to set the value of the variable */
|
||||||
|
|
||||||
if (!Getattr(n,"feature:immutable")) {
|
int assignable = is_assignable(n);
|
||||||
|
|
||||||
|
if (assignable) {
|
||||||
int make_wrapper = 1;
|
int make_wrapper = 1;
|
||||||
String *tm = 0;
|
String *tm = 0;
|
||||||
String *target = 0;
|
String *target = 0;
|
||||||
|
|
@ -1261,7 +1206,6 @@ Language::membervariableHandler(Node *n) {
|
||||||
int flags = Extend | SmartPointer;
|
int flags = Extend | SmartPointer;
|
||||||
//if (CPlusPlus) flags |= CWRAP_VAR_REFERENCE;
|
//if (CPlusPlus) flags |= CWRAP_VAR_REFERENCE;
|
||||||
Swig_MembersetToFunction(n,ClassType, flags);
|
Swig_MembersetToFunction(n,ClassType, flags);
|
||||||
if (CPlusPlus) patch_parms(Getattr(n,"parms"));
|
|
||||||
if (!Extend) {
|
if (!Extend) {
|
||||||
/* Check for a member in typemap here */
|
/* Check for a member in typemap here */
|
||||||
|
|
||||||
|
|
@ -1295,7 +1239,6 @@ Language::membervariableHandler(Node *n) {
|
||||||
/* Emit get function */
|
/* Emit get function */
|
||||||
{
|
{
|
||||||
Swig_MembergetToFunction(n,ClassType,Extend | SmartPointer);
|
Swig_MembergetToFunction(n,ClassType,Extend | SmartPointer);
|
||||||
if (CPlusPlus) patch_parms(Getattr(n,"parms"));
|
|
||||||
Setattr(n,"sym:name", mrename_get);
|
Setattr(n,"sym:name", mrename_get);
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
}
|
}
|
||||||
|
|
@ -2122,11 +2065,7 @@ int
|
||||||
Language::constructorHandler(Node *n) {
|
Language::constructorHandler(Node *n) {
|
||||||
Swig_require("constructorHandler",n,"?name","*sym:name","?type","?parms",NIL);
|
Swig_require("constructorHandler",n,"?name","*sym:name","?type","?parms",NIL);
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
String *mrename;
|
String *mrename = Swig_name_construct(symname);
|
||||||
Parm *parms = Getattr(n,"parms");
|
|
||||||
|
|
||||||
mrename = Swig_name_construct(symname);
|
|
||||||
if (CPlusPlus) patch_parms(parms);
|
|
||||||
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor_code, CPlusPlus, Getattr(n, "template") ? 0 :Extend);
|
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor_code, CPlusPlus, Getattr(n, "template") ? 0 :Extend);
|
||||||
Setattr(n,"sym:name", mrename);
|
Setattr(n,"sym:name", mrename);
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
|
|
@ -2143,10 +2082,7 @@ int
|
||||||
Language::copyconstructorHandler(Node *n) {
|
Language::copyconstructorHandler(Node *n) {
|
||||||
Swig_require("copyconstructorHandler",n,"?name","*sym:name","?type","?parms", NIL);
|
Swig_require("copyconstructorHandler",n,"?name","*sym:name","?type","?parms", NIL);
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
String *mrename;
|
String *mrename = Swig_name_copyconstructor(symname);
|
||||||
Parm *parms = Getattr(n,"parms");
|
|
||||||
if (CPlusPlus) patch_parms(parms);
|
|
||||||
mrename = Swig_name_copyconstructor(symname);
|
|
||||||
Swig_ConstructorToFunction(n,ClassType, none_comparison, director_ctor_code,
|
Swig_ConstructorToFunction(n,ClassType, none_comparison, director_ctor_code,
|
||||||
CPlusPlus, Getattr(n,"template") ? 0 : Extend);
|
CPlusPlus, Getattr(n,"template") ? 0 : Extend);
|
||||||
Setattr(n,"sym:name", mrename);
|
Setattr(n,"sym:name", mrename);
|
||||||
|
|
@ -2294,12 +2230,12 @@ int Language::variableWrapper(Node *n) {
|
||||||
String *name = Getattr(n,"name");
|
String *name = Getattr(n,"name");
|
||||||
|
|
||||||
/* If no way to set variables. We simply create functions */
|
/* If no way to set variables. We simply create functions */
|
||||||
if (!Getattr(n,"feature:immutable")) {
|
int assignable = is_assignable(n);
|
||||||
|
if (assignable) {
|
||||||
int make_wrapper = 1;
|
int make_wrapper = 1;
|
||||||
String *tm = Swig_typemap_lookup_new("globalin", n, name, 0);
|
String *tm = Swig_typemap_lookup_new("globalin", n, name, 0);
|
||||||
|
|
||||||
Swig_VarsetToFunction(n);
|
Swig_VarsetToFunction(n);
|
||||||
if (CPlusPlus) patch_parms(Getattr(n,"parms"));
|
|
||||||
|
|
||||||
Setattr(n,"sym:name", Swig_name_set(symname));
|
Setattr(n,"sym:name", Swig_name_set(symname));
|
||||||
|
|
||||||
|
|
@ -2326,7 +2262,6 @@ int Language::variableWrapper(Node *n) {
|
||||||
Setattr(n,"name",name);
|
Setattr(n,"name",name);
|
||||||
}
|
}
|
||||||
Swig_VargetToFunction(n);
|
Swig_VargetToFunction(n);
|
||||||
if (CPlusPlus) patch_parms(Getattr(n,"parms"));
|
|
||||||
Setattr(n,"sym:name", Swig_name_get(symname));
|
Setattr(n,"sym:name", Swig_name_get(symname));
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
Swig_restore(n);
|
Swig_restore(n);
|
||||||
|
|
@ -2631,3 +2566,25 @@ void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
|
||||||
Delete(argv_template_string);
|
Delete(argv_template_string);
|
||||||
argv_template_string = Copy(argv);
|
argv_template_string = Copy(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Language::is_assignable(Node *n)
|
||||||
|
{
|
||||||
|
if (Getattr(n,"feature:immutable")) return 0;
|
||||||
|
SwigType *type = Getattr(n,"type");
|
||||||
|
Node *cn = 0;
|
||||||
|
SwigType *ftd = SwigType_typedef_resolve_all(type);
|
||||||
|
SwigType *td = SwigType_strip_qualifiers(ftd);
|
||||||
|
if (SwigType_type(td) == T_USER) {
|
||||||
|
if ((cn = Swig_symbol_clookup(td,0))) {
|
||||||
|
if ((Strcmp(nodeType(cn),"class") == 0)) {
|
||||||
|
if (Getattr(cn,"allocate:noassign")) {
|
||||||
|
Setattr(n,"feature:immutable","1");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@ public:
|
||||||
|
|
||||||
SWIG_library_directory("python");
|
SWIG_library_directory("python");
|
||||||
|
|
||||||
|
|
||||||
|
/* Turn on safe value wrapper use mode */
|
||||||
|
Swig_value_wrapper_mode(1);
|
||||||
|
|
||||||
/* Turn on template extmode */
|
/* Turn on template extmode */
|
||||||
Wrapper_template_extmode_set(1);
|
Wrapper_template_extmode_set(1);
|
||||||
|
|
||||||
|
|
@ -1467,7 +1471,11 @@ public:
|
||||||
Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name);
|
Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((shadow) && (checkAttribute(n,"feature:immutable","1"))) {
|
int assignable = is_assignable(n);
|
||||||
|
|
||||||
|
Printf(stderr,"name %s %s\n",name, Getattr(n,"allocate:noassign"));
|
||||||
|
|
||||||
|
if ((shadow) && assignable) {
|
||||||
if (!in_class) {
|
if (!in_class) {
|
||||||
Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname);
|
Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname);
|
||||||
}
|
}
|
||||||
|
|
@ -1477,7 +1485,7 @@ public:
|
||||||
|
|
||||||
/* Create a function for setting the value of the variable */
|
/* Create a function for setting the value of the variable */
|
||||||
|
|
||||||
if (!Getattr(n,"feature:immutable")) {
|
if (assignable) {
|
||||||
Printf(setf->def,"static int %s_set(PyObject *_val) {", wname);
|
Printf(setf->def,"static int %s_set(PyObject *_val) {", wname);
|
||||||
if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
|
if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
|
||||||
Replaceall(tm,"$source","_val");
|
Replaceall(tm,"$source","_val");
|
||||||
|
|
@ -2658,15 +2666,15 @@ public:
|
||||||
shadow = oldshadow;
|
shadow = oldshadow;
|
||||||
|
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
int immutable = (Getattr(n,"feature:immutable") != NULL);
|
int assignable = is_assignable(n);
|
||||||
if (!modern) {
|
if (!modern) {
|
||||||
if (!immutable) {
|
if (assignable) {
|
||||||
Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL);
|
Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL);
|
||||||
}
|
}
|
||||||
Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL);
|
Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL);
|
||||||
}
|
}
|
||||||
if (!classic) {
|
if (!classic) {
|
||||||
if (immutable) {
|
if (!assignable) {
|
||||||
Printv(f_shadow,tab4, modern ? "" : "if _newclass:",
|
Printv(f_shadow,tab4, modern ? "" : "if _newclass:",
|
||||||
symname," = property(", module, ".",
|
symname," = property(", module, ".",
|
||||||
Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL);
|
Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue