mirror of https://github.com/swig/swig
More refactoring for internal destructor and constructor names
Further removal of template parameters from the "name" attribute for constructors and destructors. Add test case for templated constructor instantiations - based on the Python and Octave only li_std_pair_extra.i test which caused problems making this change.
This commit is contained in:
parent
525426911c
commit
eb18619178
|
@ -21,6 +21,16 @@ public class template_templated_constructors_runme {
|
|||
TClass2Int tc2a = new TClass2Int();
|
||||
TClass2Int tc2b = new TClass2Int(123.4);
|
||||
|
||||
DoublePair double_pair = new DoublePair(1.1, 2.2);
|
||||
ShortPair short_pair = new ShortPair((short)0, (short)1);
|
||||
StringPair string_pair = new StringPair("10", "11");
|
||||
IntPair ip1 = new IntPair();
|
||||
IntPair ip2 = new IntPair(20, 21);
|
||||
IntPair ip3 = new IntPair(ip1);
|
||||
IntPair ip4 = new IntPair(short_pair);
|
||||
// These next two use IntPair constructors, unlike Python which requires factory function calls
|
||||
IntPair ip5 = new IntPair(double_pair);
|
||||
IntPair ip6 = new IntPair(string_pair);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
from template_templated_constructors import *
|
||||
|
||||
t1 = TConstructor1(123)
|
||||
t2a = TConstructor2()
|
||||
t2b = TConstructor2(123)
|
||||
|
||||
tc1 = TClass1Int(123.4)
|
||||
tc2a = TClass2Int()
|
||||
tc2b = TClass2Int(123.4)
|
||||
|
||||
double_pair = DoublePair(1.1, 2.2)
|
||||
short_pair = ShortPair(0, 1)
|
||||
string_pair = StringPair("10", "11")
|
||||
ip1 = IntPair()
|
||||
ip2 = IntPair(20, 21)
|
||||
ip3 = IntPair(ip1)
|
||||
ip4 = IntPair(short_pair)
|
||||
# These next two create an IntPair from factory function calls in Python, unlike Java which calls the IntPair constructor
|
||||
ip5 = Pair(double_pair)
|
||||
ip6 = MakeStringPair(string_pair)
|
|
@ -59,3 +59,37 @@ public:
|
|||
%extend ConstructSpace::TClass2<int> {
|
||||
%template(TClass2Int) TClass2<double>;
|
||||
}
|
||||
|
||||
%inline %{
|
||||
// Simple version of std::pair
|
||||
namespace Standard {
|
||||
template <class T, class U > struct Pair {
|
||||
typedef T first_type;
|
||||
typedef U second_type;
|
||||
Pair() {}
|
||||
Pair(const T& first, const U& second) {}
|
||||
Pair(const Pair& other) {}
|
||||
|
||||
template <class U1, class U2> Pair(const Pair< U1, U2 > &otherone) {}
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
namespace Standard {
|
||||
%template(StringPair) Pair<std::string, std::string>;
|
||||
%template(ShortPair) Pair<short, short>;
|
||||
%template(IntPair) Pair<int, int>;
|
||||
%template(DoublePair) Pair<double, double>;
|
||||
%extend Pair<int, int> {
|
||||
// Templated constructor which uses 'correct' name of the containing class (IntPair)
|
||||
%template(IntPair) Pair<short, short>;
|
||||
// Templated constructors that behave differently in different languages as the template name
|
||||
// does not match IntPair, the instantiated name for Pair<int, int>.
|
||||
// Some languages wrap as a factory style function (Python),
|
||||
// others ignore the name and wrap as regular constructor (Java).
|
||||
%template(Pair) Pair<double, double>;
|
||||
%template(MakeStringPair) Pair<std::string, std::string>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,25 +224,16 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
|
|||
}
|
||||
}
|
||||
} else if (Equal(nodeType, "constructor")) {
|
||||
String *name = Getattr(n, "name");
|
||||
if (!(Getattr(n, "templatetype"))) {
|
||||
String *symname;
|
||||
String *stripped_name = SwigType_templateprefix(name);
|
||||
if (Strstr(tname, stripped_name)) {
|
||||
Replaceid(name, stripped_name, tname);
|
||||
}
|
||||
Delete(stripped_name);
|
||||
symname = Getattr(n, "sym:name");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *name;
|
||||
if (symname) {
|
||||
stripped_name = SwigType_templateprefix(symname);
|
||||
String *stripped_name = SwigType_templateprefix(symname);
|
||||
if (Strstr(tname, stripped_name)) {
|
||||
Replaceid(symname, stripped_name, tname);
|
||||
}
|
||||
Delete(stripped_name);
|
||||
}
|
||||
if (strchr(Char(name), '<')) {
|
||||
Append(patchlist, Getattr(n, "name"));
|
||||
}
|
||||
name = Getattr(n, "sym:name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<')) {
|
||||
|
@ -266,21 +257,9 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
|
|||
* template node, with the special exception for %extend which adds its methods under an intermediate node. */
|
||||
Node* parent = parentNode(n);
|
||||
if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
|
||||
String *name = Getattr(n, "name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<'))
|
||||
Append(patchlist, Getattr(n, "name"));
|
||||
}
|
||||
name = Getattr(n, "sym:name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<')) {
|
||||
String *sn = Copy(tname);
|
||||
Setattr(n, "sym:name", sn);
|
||||
Delete(sn);
|
||||
} else {
|
||||
Replace(name, tname, rname, DOH_REPLACE_ANY);
|
||||
}
|
||||
}
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
if (symname)
|
||||
Replace(symname, tname, rname, DOH_REPLACE_ANY);
|
||||
Append(cpatchlist, Getattr(n, "code"));
|
||||
}
|
||||
} else if (Equal(nodeType, "using")) {
|
||||
|
@ -478,7 +457,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
List *patchlist, *cpatchlist, *typelist;
|
||||
String *templateargs;
|
||||
String *tname;
|
||||
String *iname;
|
||||
String *name_with_templateargs = 0;
|
||||
String *tbase;
|
||||
Parm *unexpanded_variadic_parm = 0;
|
||||
ParmList *expanded_variadic_parms = 0;
|
||||
|
@ -551,9 +530,12 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
{
|
||||
String *name = Getattr(n, "name");
|
||||
if (name) {
|
||||
Append(name, templateargs);
|
||||
String *nodeType = nodeType(n);
|
||||
name_with_templateargs = NewStringf("%s%s", name, templateargs);
|
||||
if (!(Equal(nodeType, "constructor") || Equal(nodeType, "destructor"))) {
|
||||
Setattr(n, "name", name_with_templateargs);
|
||||
}
|
||||
}
|
||||
iname = name;
|
||||
}
|
||||
|
||||
/* Patch all of the types */
|
||||
|
@ -609,12 +591,12 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
Node *tynode = Swig_symbol_clookup(s, 0);
|
||||
String *tyname = tynode ? Getattr(tynode, "sym:name") : 0;
|
||||
/*
|
||||
Printf(stdout, " replacing %s with %s to %s or %s to %s\n", s, name, dvalue, tbase, iname);
|
||||
Printf(stdout, " replacing %s with %s to %s or %s to %s\n", s, name, dvalue, tbase, name_with_templateargs);
|
||||
Printf(stdout, " %d %s to %s\n", tp == unexpanded_variadic_parm, name, ParmList_str_defaultargs(expanded_variadic_parms));
|
||||
*/
|
||||
if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) {
|
||||
SwigType_typename_replace(s, name, dvalue);
|
||||
SwigType_typename_replace(s, tbase, iname);
|
||||
SwigType_typename_replace(s, tbase, name_with_templateargs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -645,7 +627,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
String *s = Getitem(typelist, i);
|
||||
assert(!SwigType_isvariadic(s)); /* All parameters should have already been expanded, this is for function that contain variadic parameters only, such as f(v.p.V) */
|
||||
SwigType_variadic_replace(s, unexpanded_variadic_parm, expanded_variadic_parms);
|
||||
SwigType_typename_replace(s, tbase, iname);
|
||||
SwigType_typename_replace(s, tbase, name_with_templateargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -664,6 +646,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
}
|
||||
}
|
||||
}
|
||||
Delete(name_with_templateargs);
|
||||
Delete(patchlist);
|
||||
Delete(cpatchlist);
|
||||
Delete(typelist);
|
||||
|
@ -671,7 +654,6 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
Delete(tname);
|
||||
Delete(templateargs);
|
||||
|
||||
/* set_nodeType(n,"template"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2555,13 +2555,18 @@ int Language::constructorDeclaration(Node *n) {
|
|||
return SWIG_NOWRAP;
|
||||
}
|
||||
|
||||
/* Name adjustment for %rename */
|
||||
// Name adjustment of constructor when a class has been renamed with %rename
|
||||
Swig_save("constructorDeclaration", n, "sym:name", NIL);
|
||||
|
||||
{
|
||||
String *base = Swig_scopename_last(name);
|
||||
if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
|
||||
Setattr(n, "sym:name", ClassPrefix);
|
||||
// Note that it is possible for the constructor to have a different name to the class name in
|
||||
// some target languages, where it is wrapped as a factory type function instead of a constructor.
|
||||
if (Equal(base, symname) && !Equal(symname, ClassPrefix)) {
|
||||
// Adjust name, except when the constructor's name comes from a templated constructor,
|
||||
// where the name passed to %template is used instead.
|
||||
if (!Getattr(n, "template"))
|
||||
Setattr(n, "sym:name", ClassPrefix);
|
||||
}
|
||||
Delete(base);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue