add tests and fix the value wrapper for opaque types, including the template cases
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6374 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
8c9152c376
commit
cf81f4a4e9
3 changed files with 134 additions and 9 deletions
|
|
@ -119,6 +119,7 @@ CPP_TEST_CASES += \
|
||||||
director_basic \
|
director_basic \
|
||||||
director_detect \
|
director_detect \
|
||||||
director_default \
|
director_default \
|
||||||
|
director_enum \
|
||||||
director_exception \
|
director_exception \
|
||||||
director_frob \
|
director_frob \
|
||||||
director_finalizer \
|
director_finalizer \
|
||||||
|
|
@ -288,6 +289,7 @@ CPP_TEST_CASES += \
|
||||||
valuewrapper_base \
|
valuewrapper_base \
|
||||||
valuewrapper_const \
|
valuewrapper_const \
|
||||||
valuewrapper_default \
|
valuewrapper_default \
|
||||||
|
valuewrapper_opaque \
|
||||||
varargs \
|
varargs \
|
||||||
virtual_destructor \
|
virtual_destructor \
|
||||||
virtual_poly \
|
virtual_poly \
|
||||||
|
|
|
||||||
96
SWIG/Examples/test-suite/valuewrapper_opaque.i
Normal file
96
SWIG/Examples/test-suite/valuewrapper_opaque.i
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
%module valuewrapper_opaque
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opaque types
|
||||||
|
*/
|
||||||
|
%{
|
||||||
|
template<typename T> class TemplateClass {
|
||||||
|
public:
|
||||||
|
TemplateClass<T>(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<Klass> getKlass(Klass k) {
|
||||||
|
TemplateClass<Klass> t(k);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateClass<A> getA(A a) {
|
||||||
|
TemplateClass<A> t(a);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateClass<B> getA(B b) {
|
||||||
|
TemplateClass<B> t(b);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateClass<C> getC(C a) {
|
||||||
|
TemplateClass<C> t(a);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateClass<int> getInt(int a) {
|
||||||
|
TemplateClass<int> t(a);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
A sgetA(A a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Klass sgetKlass(Klass a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct auto_ptr
|
||||||
|
{
|
||||||
|
auto_ptr(T a){}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto_ptr<A> getPtrA(auto_ptr<A> a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
B getB(B a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template() auto_ptr<A>;
|
||||||
|
|
@ -329,26 +329,51 @@ static Parm *nonvoid_parms(Parm *p) {
|
||||||
* use the %template directive (unnamed or not) to help SWIG decide whether or not
|
* use the %template directive (unnamed or not) to help SWIG decide whether or not
|
||||||
* SwigValueWrapper should be used, for example
|
* SwigValueWrapper should be used, for example
|
||||||
* %template() std::auto_ptr<int>; // unnamed %template does not generate any proxy classes
|
* %template() std::auto_ptr<int>; // 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) {
|
SwigType *cplus_value_type(SwigType *t) {
|
||||||
Node *n = 0;
|
Node *n = 0;
|
||||||
String *s = 0;
|
int use_wrapper = 1;
|
||||||
if (CPlusPlus) {
|
if (CPlusPlus) {
|
||||||
if (SwigType_isclass(t)) {
|
if (SwigType_type(t) == T_USER) {
|
||||||
SwigType *ftd = SwigType_typedef_resolve_all(t);
|
SwigType *ftd = SwigType_typedef_resolve_all(t);
|
||||||
SwigType *td = SwigType_strip_qualifiers(ftd);
|
SwigType *td = SwigType_strip_qualifiers(ftd);
|
||||||
if ((n = Swig_symbol_clookup(td,0))) {
|
if ((n = Swig_symbol_clookup(td,0))) {
|
||||||
if ((Strcmp(nodeType(n),"class") == 0) && (!Getattr(n,"allocate:default_constructor") || (Getattr(n,"allocate:noassign")))) {
|
if (((Strcmp(nodeType(n),"class") == 0)
|
||||||
s = NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0));
|
&& !Getattr(n,"allocate:noassign")
|
||||||
|
&& (Getattr(n,"allocate:default_constructor")))
|
||||||
|
|| (Getattr(n,"feature:novaluewrapper")
|
||||||
|
&& !Getattr(n,"feature:valuewrapper"))) {
|
||||||
|
use_wrapper = 0;
|
||||||
}
|
}
|
||||||
} else if (SwigType_issimple(td) && SwigType_istemplate(td)) {
|
|
||||||
s = NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0));
|
|
||||||
}
|
}
|
||||||
Delete(ftd);
|
Delete(ftd);
|
||||||
Delete(td);
|
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 */
|
/* Patch C++ pass-by-value */
|
||||||
|
|
@ -1229,7 +1254,9 @@ Language::membervariableHandler(Node *n) {
|
||||||
target = NewStringf("%s->%s", Swig_cparm_name(0,0),name);
|
target = NewStringf("%s->%s", Swig_cparm_name(0,0),name);
|
||||||
tm = Swig_typemap_lookup_new("memberin",n,target,0);
|
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) {
|
if (!Extend) {
|
||||||
/* Check for a member in typemap here */
|
/* Check for a member in typemap here */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue