mirror of https://github.com/swig/swig
Allow an instantiated template to have the same name as the C++ template name
For example, this is now possible: template<typename T> struct X { ... }; %template(X) X<int>; Closes #1100.
This commit is contained in:
parent
d37e41fed8
commit
e27a606335
|
@ -7,6 +7,13 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.0.0 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2017-09-29: wsfulton
|
||||||
|
Issue #1100 - Allow an instantiated template to have the same name in the target
|
||||||
|
language as the C++ template name, for example, this is now possible:
|
||||||
|
|
||||||
|
template<typename T> struct X { ... };
|
||||||
|
%template(X) X<int>;
|
||||||
|
|
||||||
2017-09-23: wsfulton
|
2017-09-23: wsfulton
|
||||||
Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
|
Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
%module cpp_template_duplicate_names
|
||||||
|
|
||||||
|
// From test-suite/template_class_reuse.i test
|
||||||
|
|
||||||
|
%{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate1 { void f(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate1;
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate1 { void f(){}; };
|
||||||
|
template <bool B> struct Duplicate1 { void f(){}; };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate2;
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <int I> struct Duplicate2 { void n(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%template(Duplicate2_0) Space::Duplicate2<0>;
|
||||||
|
%template(Duplicate2_0) Space::Duplicate2<0>;
|
||||||
|
|
||||||
|
|
||||||
|
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate3;
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <int I> struct Duplicate3 { void n(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%template(Duplicate3) Space::Duplicate3<0>;
|
||||||
|
%template(Duplicate3) Space::Duplicate3<0>;
|
||||||
|
|
||||||
|
|
||||||
|
%{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate4 { void f(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate4;
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate4 { void f(){}; };
|
||||||
|
template <bool B> struct Duplicate4 { void f(){}; };
|
||||||
|
}
|
||||||
|
%template(Duplicate4) Space::Duplicate4<0>;
|
||||||
|
%template(Duplicate4) Space::Duplicate4<0>;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
|
||||||
|
cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
|
||||||
|
cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
|
||||||
|
cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
|
||||||
|
cpp_template_duplicate_names.i:25: Warning 302: Identifier 'Duplicate2_0' redefined (ignored) (Renamed from 'Duplicate2< 0 >'),
|
||||||
|
cpp_template_duplicate_names.i:24: Warning 302: previous definition of 'Duplicate2_0' (Renamed from 'Duplicate2< 0 >').
|
||||||
|
cpp_template_duplicate_names.i:35: Warning 302: Identifier 'Duplicate3' redefined (ignored) (Renamed from 'Duplicate3< 0 >'),
|
||||||
|
cpp_template_duplicate_names.i:31: Warning 302: previous definition of 'Duplicate3'.
|
||||||
|
cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
|
||||||
|
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
|
||||||
|
cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
|
||||||
|
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
|
||||||
|
cpp_template_duplicate_names.i:50: Warning 302: Identifier 'Duplicate4' redefined (ignored) (Renamed from 'Duplicate4< 0 >'),
|
||||||
|
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
|
|
@ -0,0 +1,57 @@
|
||||||
|
import template_class_reuse_name.*;
|
||||||
|
|
||||||
|
public class template_class_reuse_name_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("template_class_reuse_name");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[])
|
||||||
|
{
|
||||||
|
new Bool1().tt();
|
||||||
|
new Bool1False().ff();
|
||||||
|
|
||||||
|
new Bool2().tt();
|
||||||
|
new Bool2False().ff();
|
||||||
|
|
||||||
|
new Bool3().tt();
|
||||||
|
new Bool3False().ff();
|
||||||
|
|
||||||
|
new Bool4().tt();
|
||||||
|
new Bool4False().ff();
|
||||||
|
|
||||||
|
|
||||||
|
new BoolForward1().tt();
|
||||||
|
new BoolForward1False().ff();
|
||||||
|
|
||||||
|
new BoolForward2().tt();
|
||||||
|
new BoolForward2False().ff();
|
||||||
|
|
||||||
|
new BoolForward3().tt();
|
||||||
|
new BoolForward3False().ff();
|
||||||
|
|
||||||
|
new BoolForward4().tt();
|
||||||
|
new BoolForward4False().ff();
|
||||||
|
|
||||||
|
|
||||||
|
new IntBool1().tt();
|
||||||
|
new IntBool1False().ff();
|
||||||
|
|
||||||
|
new IntBool2().tt();
|
||||||
|
new IntBool2False().ff();
|
||||||
|
|
||||||
|
new IntBool3().tt();
|
||||||
|
new IntBool3False().ff();
|
||||||
|
|
||||||
|
new IntBool4().tt();
|
||||||
|
new IntBool4False().ff();
|
||||||
|
|
||||||
|
new Duplicate2_0().n();
|
||||||
|
new Duplicate3().n();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
from template_class_reuse_name import *
|
||||||
|
|
||||||
|
Bool1().tt()
|
||||||
|
Bool1False().ff()
|
||||||
|
|
||||||
|
Bool2().tt()
|
||||||
|
Bool2False().ff()
|
||||||
|
|
||||||
|
Bool3().tt()
|
||||||
|
Bool3False().ff()
|
||||||
|
|
||||||
|
Bool4().tt()
|
||||||
|
Bool4False().ff()
|
||||||
|
|
||||||
|
|
||||||
|
BoolForward1().tt()
|
||||||
|
BoolForward1False().ff()
|
||||||
|
|
||||||
|
BoolForward2().tt()
|
||||||
|
BoolForward2False().ff()
|
||||||
|
|
||||||
|
BoolForward3().tt()
|
||||||
|
BoolForward3False().ff()
|
||||||
|
|
||||||
|
BoolForward4().tt()
|
||||||
|
BoolForward4False().ff()
|
||||||
|
|
||||||
|
|
||||||
|
IntBool1().tt()
|
||||||
|
IntBool1False().ff()
|
||||||
|
|
||||||
|
IntBool2().tt()
|
||||||
|
IntBool2False().ff()
|
||||||
|
|
||||||
|
IntBool3().tt()
|
||||||
|
IntBool3False().ff()
|
||||||
|
|
||||||
|
IntBool4().tt()
|
||||||
|
IntBool4False().ff()
|
||||||
|
|
||||||
|
Duplicate2_0().n()
|
||||||
|
Duplicate3().n()
|
|
@ -0,0 +1,132 @@
|
||||||
|
%module template_class_reuse_name
|
||||||
|
|
||||||
|
// One parameter templates
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Bool1 { void tt(){}; void ff(){}; };
|
||||||
|
template <bool B = true> struct Bool2 { void tt(){}; void ff(){}; };
|
||||||
|
template <bool B> struct Bool3 {};
|
||||||
|
template <> struct Bool3<true> { void tt(){}; };
|
||||||
|
template <> struct Bool3<false> { void ff(){}; };
|
||||||
|
template <bool B = true> struct Bool4 { void tt(){}; };
|
||||||
|
template <> struct Bool4<false> { void ff(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Instantiated names are the same as C++ template name
|
||||||
|
%template(Bool1) Space::Bool1<true>;
|
||||||
|
%template(Bool2) Space::Bool2<true>;
|
||||||
|
%template(Bool3) Space::Bool3<true>;
|
||||||
|
%template(Bool4) Space::Bool4<true>;
|
||||||
|
|
||||||
|
// Instantiated names are not the same as C++ template name
|
||||||
|
%template(Bool1False) Space::Bool1<false>;
|
||||||
|
%template(Bool2False) Space::Bool2<false>;
|
||||||
|
%template(Bool3False) Space::Bool3<false>;
|
||||||
|
%template(Bool4False) Space::Bool4<false>;
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declarated templates
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct BoolForward1;
|
||||||
|
template <bool B> struct BoolForward2;
|
||||||
|
template <bool B> struct BoolForward3;
|
||||||
|
template <bool B> struct BoolForward4;
|
||||||
|
|
||||||
|
template <bool B> struct BoolForward1 { void tt(){}; void ff(){}; };
|
||||||
|
template <bool B = true> struct BoolForward2 { void tt(){}; void ff(){}; };
|
||||||
|
template <bool B> struct BoolForward3 {};
|
||||||
|
template <> struct BoolForward3<true> { void tt(){}; };
|
||||||
|
template <> struct BoolForward3<false> { void ff(){}; };
|
||||||
|
template <bool B = true> struct BoolForward4 { void tt(){}; };
|
||||||
|
template <> struct BoolForward4<false> { void ff(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Instantiated names are the same as C++ template name
|
||||||
|
%template(BoolForward1) Space::BoolForward1<true>;
|
||||||
|
%template(BoolForward2) Space::BoolForward2<true>;
|
||||||
|
%template(BoolForward3) Space::BoolForward3<true>;
|
||||||
|
%template(BoolForward4) Space::BoolForward4<true>;
|
||||||
|
|
||||||
|
// Instantiated names are not the same as C++ template name
|
||||||
|
%template(BoolForward1False) Space::BoolForward1<false>;
|
||||||
|
%template(BoolForward2False) Space::BoolForward2<false>;
|
||||||
|
%template(BoolForward3False) Space::BoolForward3<false>;
|
||||||
|
%template(BoolForward4False) Space::BoolForward4<false>;
|
||||||
|
|
||||||
|
|
||||||
|
// Two parameter templates
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <int I, bool B> struct IntBool1 { void tt(){}; void ff(){}; };
|
||||||
|
template <int I, bool B = true> struct IntBool2 { void tt(){}; void ff(){}; };
|
||||||
|
template <int I, bool B> struct IntBool3 {};
|
||||||
|
template <int I> struct IntBool3<I, true> { void tt(){}; };
|
||||||
|
template <int I> struct IntBool3<I, false> { void ff(){}; };
|
||||||
|
template <int I, bool B = true> struct IntBool4 { void tt(){}; };
|
||||||
|
template <int I> struct IntBool4<I, false> { void ff(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Instantiated names are the same as C++ template name
|
||||||
|
%template(IntBool1) Space::IntBool1<0, true>;
|
||||||
|
%template(IntBool2) Space::IntBool2<0, true>;
|
||||||
|
%template(IntBool3) Space::IntBool3<0, true>;
|
||||||
|
%template(IntBool4) Space::IntBool4<0, true>;
|
||||||
|
|
||||||
|
// Instantiated names are not the same as C++ template name
|
||||||
|
%template(IntBool1False) Space::IntBool1<0, false>;
|
||||||
|
%template(IntBool2False) Space::IntBool2<0, false>;
|
||||||
|
%template(IntBool3False) Space::IntBool3<0, false>;
|
||||||
|
%template(IntBool4False) Space::IntBool4<0, false>;
|
||||||
|
|
||||||
|
|
||||||
|
%{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate1 { void ff(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate1;
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate1 { void ff(){}; };
|
||||||
|
template <bool B> struct Duplicate1 { void ff(){}; };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate2;
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <int I> struct Duplicate2 { void n(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%template(Duplicate2_0) Space::Duplicate2<0>;
|
||||||
|
%template(Duplicate2_0) Space::Duplicate2<0>;
|
||||||
|
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate3;
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
template <int I> struct Duplicate3 { void n(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%template(Duplicate3) Space::Duplicate3<0>;
|
||||||
|
%template(Duplicate3) Space::Duplicate3<0>;
|
||||||
|
|
||||||
|
|
||||||
|
%{
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate4 { void ff(){}; };
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate4;
|
||||||
|
namespace Space {
|
||||||
|
template <bool B> struct Duplicate4 { void ff(){}; };
|
||||||
|
template <bool B> struct Duplicate4 { void ff(){}; };
|
||||||
|
}
|
||||||
|
%template(Duplicate4) Space::Duplicate4<0>;
|
||||||
|
%template(Duplicate4) Space::Duplicate4<0>;
|
||||||
|
|
|
@ -690,7 +690,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
||||||
Hash *c, *cn, *cl = 0;
|
Hash *c, *cl = 0;
|
||||||
SwigType *decl, *ndecl;
|
SwigType *decl, *ndecl;
|
||||||
String *cstorage, *nstorage;
|
String *cstorage, *nstorage;
|
||||||
int nt = 0, ct = 0;
|
int nt = 0, ct = 0;
|
||||||
|
@ -756,10 +756,9 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
||||||
(1) A conflict between a class/enum and a typedef declaration is okay.
|
(1) A conflict between a class/enum and a typedef declaration is okay.
|
||||||
In this case, the symbol table entry is set to the class/enum declaration
|
In this case, the symbol table entry is set to the class/enum declaration
|
||||||
itself, not the typedef.
|
itself, not the typedef.
|
||||||
|
|
||||||
(2) A conflict between namespaces is okay--namespaces are open
|
(2) A conflict between namespaces is okay--namespaces are open
|
||||||
|
|
||||||
(3) Otherwise, overloading is only allowed for functions
|
(3) Otherwise, overloading is only allowed for functions
|
||||||
|
(4) This special case is okay: a class template instantiated with same name as the template's name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Check for namespaces */
|
/* Check for namespaces */
|
||||||
|
@ -777,6 +776,25 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
||||||
Setattr(n, "sym:previousSibling", pcl);
|
Setattr(n, "sym:previousSibling", pcl);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Special case: class template instantiated with same name as the template's name eg: %template(X) X<int>; */
|
||||||
|
if (Equal(nodeType(c), "template")) {
|
||||||
|
String *nt1 = Getattr(c, "templatetype");
|
||||||
|
String *nt2 = nodeType(n);
|
||||||
|
if (Equal(nt1, "class") && Equal(nt1, nt2)) {
|
||||||
|
if (Getattr(n, "template")) {
|
||||||
|
/* Finally check that another %template with same name doesn't already exist */
|
||||||
|
if (!Getattr(c, "sym:nextSibling")) {
|
||||||
|
Setattr(c, "sym:nextSibling", n);
|
||||||
|
Setattr(n, "sym:symtab", current_symtab);
|
||||||
|
Setattr(n, "sym:name", symname);
|
||||||
|
Setattr(n, "sym:previousSibling", c);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Getattr(n, "allows_typedef"))
|
if (Getattr(n, "allows_typedef"))
|
||||||
nt = 1;
|
nt = 1;
|
||||||
if (Getattr(c, "allows_typedef"))
|
if (Getattr(c, "allows_typedef"))
|
||||||
|
@ -857,7 +875,7 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
||||||
String *nt = Getattr(n, "nodeType");
|
String *nt = Getattr(n, "nodeType");
|
||||||
int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
|
int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
|
||||||
int n_plain_cdecl = Equal(nt, "cdecl");
|
int n_plain_cdecl = Equal(nt, "cdecl");
|
||||||
cn = c;
|
Node *cn = c;
|
||||||
pn = 0;
|
pn = 0;
|
||||||
while (cn) {
|
while (cn) {
|
||||||
decl = Getattr(cn, "decl");
|
decl = Getattr(cn, "decl");
|
||||||
|
|
Loading…
Reference in New Issue