diff --git a/SWIG/Examples/test-suite/common.mk b/SWIG/Examples/test-suite/common.mk index 47b0b7882..14f868e14 100644 --- a/SWIG/Examples/test-suite/common.mk +++ b/SWIG/Examples/test-suite/common.mk @@ -119,6 +119,7 @@ CPP_TEST_CASES += \ director_basic \ director_detect \ director_default \ + director_enum \ director_exception \ director_frob \ director_finalizer \ @@ -288,6 +289,7 @@ CPP_TEST_CASES += \ valuewrapper_base \ valuewrapper_const \ valuewrapper_default \ + valuewrapper_opaque \ varargs \ virtual_destructor \ virtual_poly \ diff --git a/SWIG/Examples/test-suite/valuewrapper_opaque.i b/SWIG/Examples/test-suite/valuewrapper_opaque.i new file mode 100644 index 000000000..d961f1c7d --- /dev/null +++ b/SWIG/Examples/test-suite/valuewrapper_opaque.i @@ -0,0 +1,96 @@ +%module valuewrapper_opaque + +/* + * Opaque types + */ +%{ +template class TemplateClass { +public: +TemplateClass(T a) {} +}; + +struct B +{ +}; + +class C +{ +public: + C(int){} +}; +%} + + +/* + * Hint swig that the Opaque type B don't need the value wrapper. + * This hint is only necessary in very very special cases. + */ +%feature("novaluewrapper") B; +class B; + + +%inline %{ + +class A +{ +public: + A(int){} +}; + +class Klass {}; + + +TemplateClass getKlass(Klass k) { + TemplateClass t(k); + return t; +} + + +TemplateClass getA(A a) { + TemplateClass t(a); + return t; +} + + +TemplateClass getA(B b) { + TemplateClass t(b); + return t; +} + + +TemplateClass getC(C a) { + TemplateClass t(a); + return t; +} + + +TemplateClass getInt(int a) { + TemplateClass t(a); + return t; +} + +A sgetA(A a) { + return a; +} + +Klass sgetKlass(Klass a) { + return a; +} + +template +struct auto_ptr +{ + auto_ptr(T a){} +}; + +auto_ptr getPtrA(auto_ptr a) { + return a; +} + +B getB(B a) { + return a; +} + +%} + +%template() auto_ptr; diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index 23549e75d..b334c2c03 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -329,26 +329,51 @@ static Parm *nonvoid_parms(Parm *p) { * use the %template directive (unnamed or not) to help SWIG decide whether or not * SwigValueWrapper should be used, for example * %template() std::auto_ptr; // unnamed %template does not generate any proxy classes + * + * Upate: We turn the logic back, + * now we don't use the wrapper only when: + * 1.- We are not in CPlusPlus, ie, is C code + * 2.- Is not a user type, ie, is int,short, .... + * 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; - String *s = 0; + int use_wrapper = 1; if (CPlusPlus) { - if (SwigType_isclass(t)) { + if (SwigType_type(t) == T_USER) { SwigType *ftd = SwigType_typedef_resolve_all(t); SwigType *td = SwigType_strip_qualifiers(ftd); if ((n = Swig_symbol_clookup(td,0))) { - if ((Strcmp(nodeType(n),"class") == 0) && (!Getattr(n,"allocate:default_constructor") || (Getattr(n,"allocate:noassign")))) { - s = NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0)); - } - } else if (SwigType_issimple(td) && SwigType_istemplate(td)) { - s = NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0)); + if (((Strcmp(nodeType(n),"class") == 0) + && !Getattr(n,"allocate:noassign") + && (Getattr(n,"allocate:default_constructor"))) + || (Getattr(n,"feature:novaluewrapper") + && !Getattr(n,"feature:valuewrapper"))) { + use_wrapper = 0; + } } Delete(ftd); Delete(td); + } else { + use_wrapper = 0; } + } else { + use_wrapper = 0; } - return s; + return use_wrapper ? + NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0)) : 0; } /* Patch C++ pass-by-value */ @@ -1229,7 +1254,9 @@ Language::membervariableHandler(Node *n) { target = NewStringf("%s->%s", Swig_cparm_name(0,0),name); tm = Swig_typemap_lookup_new("memberin",n,target,0); } - Swig_MembersetToFunction(n,ClassType,Extend | SmartPointer); + int flags = Extend | SmartPointer; + //if (CPlusPlus) flags |= CWRAP_VAR_REFERENCE; + Swig_MembersetToFunction(n,ClassType, flags); if (!Extend) { /* Check for a member in typemap here */