mirror of
https://github.com/nasa/trick.git
synced 2024-12-23 06:52:26 +00:00
SWIG 4 Template Directive Changes (#1741)
* Updated convert_swig to account for template directive changes in SWIG 4 * Fixed merge issues * Merge cleanup
This commit is contained in:
parent
7b4253d703
commit
a9aa7088ad
docs/developer_docs
libexec/trick
test/SIM_test_ip
RUN_test
models/test_ip/include
@ -275,10 +275,13 @@ Add the <b>class_string</b> to the SWIG interface text.
|
|||||||
1. While there's class content text remaining to be processed,
|
1. While there's class content text remaining to be processed,
|
||||||
repeatedly search for data members that match : <b>template_name '<'</b> <i>template-params</i> <b>'>' name ;</b>
|
repeatedly search for data members that match : <b>template_name '<'</b> <i>template-params</i> <b>'>' name ;</b>
|
||||||
For each match, create a SWIG %template directive to create an instantiation
|
For each match, create a SWIG %template directive to create an instantiation
|
||||||
of the specific templated type used by the data member. Add the
|
of the specific templated type used by the data member. Due to changes in SWIG 4,
|
||||||
SWIG %template directive to the templated typedefs string that
|
template directives must be specified before their respective data members. As such,
|
||||||
Otherwise append whatever wasn't matched in process contents to
|
the template directives are inserted immediately prior to the class definition.
|
||||||
the SWIG interface text.
|
SWIG does not resolve namespaces in these directives the same as C++ does
|
||||||
|
(it will only check local scope, not global). To account for this,
|
||||||
|
if the directive specifies a template outside the local namespace, convert_swig will
|
||||||
|
escape the current namespace in the format : } template_directive namespace name {
|
||||||
|
|
||||||
## process_typedef_struct
|
## process_typedef_struct
|
||||||
|
|
||||||
|
@ -617,17 +617,15 @@ sub process_class($$$$$) {
|
|||||||
\s*[\{\:]$
|
\s*[\{\:]$
|
||||||
/sx or die "Internal error" ;
|
/sx or die "Internal error" ;
|
||||||
$class_name = $1 ;
|
$class_name = $1 ;
|
||||||
|
my $my_class_contents = $class_string ;
|
||||||
my $class_content;
|
|
||||||
$class_content .= $class_string ;
|
|
||||||
|
|
||||||
if ( $class_string !~ /\{$/ ) {
|
if ( $class_string !~ /\{$/ ) {
|
||||||
$$contents_ref =~ s/^(.*?\s*\{)//s ;
|
$$contents_ref =~ s/^(.*?\s*\{)//s ;
|
||||||
$class_content .= $1 ;
|
$my_class_contents .= $1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
|
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
|
||||||
$class_content .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
|
$my_class_contents .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
|
||||||
|
|
||||||
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
|
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
|
||||||
|
|
||||||
@ -639,20 +637,11 @@ sub process_class($$$$$) {
|
|||||||
|
|
||||||
#print "*** extracted = $extracted ***\n" ;
|
#print "*** extracted = $extracted ***\n" ;
|
||||||
#print "*** contents = $$contents_ref ***\n" ;
|
#print "*** contents = $$contents_ref ***\n" ;
|
||||||
my $save_namespace_content;
|
|
||||||
|
|
||||||
if ( $curr_namespace ne "" ) {
|
|
||||||
my @split_namespaces = split "::", $curr_namespace;
|
|
||||||
my $sanitized_namespace = $split_namespaces[-1] ;
|
|
||||||
my @namespace_split = split /namespace\s*$sanitized_namespace/, $$new_contents_ref;
|
|
||||||
$save_namespace_content = 'namespace ' . $sanitized_namespace . $namespace_split[-1];
|
|
||||||
$$new_contents_ref = join('namespace ' . $sanitized_namespace, @namespace_split[0 .. $#namespace_split-1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
# SWIG doesn't like "const static". Change it to "static const"
|
# SWIG doesn't like "const static". Change it to "static const"
|
||||||
$extracted =~ s/const\s+static/static const/g ;
|
$extracted =~ s/const\s+static/static const/g ;
|
||||||
|
|
||||||
my $isSwigExcludeBlock = 0;
|
my $isSwigExcludeBlock = 0 ;
|
||||||
|
|
||||||
# templated variables need to be declared with the SWIG %template directive.
|
# templated variables need to be declared with the SWIG %template directive.
|
||||||
# This loop looks for any templated variables and creates the %template lines.
|
# This loop looks for any templated variables and creates the %template lines.
|
||||||
@ -662,15 +651,25 @@ sub process_class($$$$$) {
|
|||||||
|
|
||||||
if ( $non_var ne "" ) {
|
if ( $non_var ne "" ) {
|
||||||
#print "*** non_var = $non_var ***\n" ;
|
#print "*** non_var = $non_var ***\n" ;
|
||||||
$class_content .= $non_var ;
|
$my_class_contents .= $non_var ;
|
||||||
my $ifndefSwig = $non_var;
|
my $ifndefSwig = $non_var;
|
||||||
if ($isSwigExcludeBlock == 0) {
|
my $moreNonVar = 1 ;
|
||||||
if ($ifndefSwig =~ /(?:ifndef\s*SWIG|if\s*!\s*defined\s*\(\s*SWIG\s*\))/ ) {
|
# search for all instances of #ifndef SWIG, #if !defined(SWIG), and #endif prior to template variable
|
||||||
$isSwigExcludeBlock = 1;
|
# update $isSwigExcludeBlock to the last instance*
|
||||||
|
# exit when no match is found
|
||||||
|
# * this script does not track preprocessor scope, so any #endif will set $isSwigExcludeBlock to 0
|
||||||
|
# in other words we don't support SWIGing nested preprocessor if statements, use at your peril
|
||||||
|
while ($moreNonVar == 1) {
|
||||||
|
if ($ifndefSwig =~ s/(#\s*ifndef\s*SWIG)|(#\s*if\s*!\s*defined\s*\(\s*SWIG\s*\))|(#\s*endif\s*)// ) {
|
||||||
|
if($1 ne "" or $2 ne "") {
|
||||||
|
$isSwigExcludeBlock = 1 ;
|
||||||
|
}
|
||||||
|
elsif($3 ne "") {
|
||||||
|
$isSwigExcludeBlock = 0 ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
if ($ifndefSwig =~ /endif/ ) {
|
$moreNonVar = 0 ;
|
||||||
$isSwigExcludeBlock = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,6 +680,7 @@ sub process_class($$$$$) {
|
|||||||
$template_var_def_str =~ /(.*?>)\s*([_A-Za-z]\w*).*?;/s ;
|
$template_var_def_str =~ /(.*?>)\s*([_A-Za-z]\w*).*?;/s ;
|
||||||
my ($template_full_type) = $1 ;
|
my ($template_full_type) = $1 ;
|
||||||
my ($var_name) = $2 ;
|
my ($var_name) = $2 ;
|
||||||
|
$my_class_contents .= $template_var_def_str ;
|
||||||
|
|
||||||
$template_full_type =~ /([_A-Za-z][:\w]*)\s*</ ;
|
$template_full_type =~ /([_A-Za-z][:\w]*)\s*</ ;
|
||||||
my ($template_type) = $1 ;
|
my ($template_type) = $1 ;
|
||||||
@ -703,28 +703,34 @@ sub process_class($$$$$) {
|
|||||||
my $identifier = "${sanitized_namespace}${class_name}_${var_name}" ;
|
my $identifier = "${sanitized_namespace}${class_name}_${var_name}" ;
|
||||||
my $trick_swig_template = "TRICK_SWIG_TEMPLATE_$identifier" ;
|
my $trick_swig_template = "TRICK_SWIG_TEMPLATE_$identifier" ;
|
||||||
|
|
||||||
my $typedef;
|
# Insert template directive immediately before intsance
|
||||||
if ($isSwigExcludeBlock == 0) {
|
# This is required as of SWIG 4
|
||||||
$typedef = "#ifndef $trick_swig_template\n" ;
|
my $typedef = "\n#ifndef $trick_swig_template\n" ;
|
||||||
$typedef .= "#define $trick_swig_template\n";
|
$typedef .= "#define $trick_swig_template\n" ;
|
||||||
if ($qualified) {
|
$typedef .= "\%template($identifier) $template_full_type;\n" ;
|
||||||
$typedef .= "\%template($identifier) $template_full_type;\n" ;
|
$typedef .= "#endif\n" ;
|
||||||
} else {
|
|
||||||
if ( $curr_namespace ne "" ) {
|
# SWIG namespace resolution for template directives starts at the local space
|
||||||
my $cppns = substr $curr_namespace, 0, -2;
|
# Therefore, if the type is qualified, assume it's fully qualified and put the
|
||||||
$typedef .= "namespace $cppns {\n";
|
# %template directive in the global namespace by escaping the current namespace
|
||||||
$typedef .= "\%template($identifier) $template_full_type;\n}\n" ;
|
if ($curr_namespace ne "") {
|
||||||
} else {
|
my $in_same_namespace = 1 ;
|
||||||
$typedef .= "\%template($identifier) $template_full_type;\n" ;
|
if ($template_full_type =~ /^\w*(::)\w+</) {
|
||||||
}
|
$in_same_namespace = 0 ;
|
||||||
}
|
}
|
||||||
$typedef .= "#endif\n\n" ;
|
if ($in_same_namespace eq 0) {
|
||||||
$$new_contents_ref .= $typedef ;
|
$curr_namespace =~ /(.*)::/ ;
|
||||||
|
$typedef = "\n}" . $typedef . "namespace " . $1 . " {" ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($isSwigExcludeBlock == 0) {
|
||||||
|
$template_typedefs .= $typedef ;
|
||||||
|
}
|
||||||
|
|
||||||
$processed_templates{$template_type_no_sp} = 1 ;
|
$processed_templates{$template_type_no_sp} = 1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$class_content .= $template_var_def_str ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,18 +738,18 @@ sub process_class($$$$$) {
|
|||||||
|
|
||||||
push @$class_names_ref , "$curr_namespace$class_name" ;
|
push @$class_names_ref , "$curr_namespace$class_name" ;
|
||||||
|
|
||||||
|
# write out the templated variable declaration lines found in this class.
|
||||||
|
$$new_contents_ref .= $template_typedefs."\n" ;
|
||||||
|
|
||||||
|
$$new_contents_ref .= $my_class_contents ;
|
||||||
# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
|
# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
|
||||||
$class_content .= $extracted . ";\n" ;
|
$$new_contents_ref .= $extracted . ";\n" ;
|
||||||
|
|
||||||
my $c_ = "$curr_namespace$class_name" ;
|
my $c_ = "$curr_namespace$class_name" ;
|
||||||
$c_ =~ s/\:/_/g ;
|
$c_ =~ s/\:/_/g ;
|
||||||
# Add a #define line that signals that this class has been processed by swig. Classes excluded in #if 0 blocks will
|
# Add a #define line that signals that this class has been processed by swig. Classes excluded in #if 0 blocks will
|
||||||
# not have this #define defined.
|
# not have this #define defined.
|
||||||
$class_content .= "#define TRICK_SWIG_DEFINED_$c_" ;
|
$$new_contents_ref .= "#define TRICK_SWIG_DEFINED_$c_" ;
|
||||||
if ( $save_namespace_content ne "" ) {
|
|
||||||
$$new_contents_ref .= $save_namespace_content;
|
|
||||||
}
|
|
||||||
$$new_contents_ref .= $class_content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## ================================================================================
|
## ================================================================================
|
||||||
|
@ -2995,6 +2995,24 @@ def main():
|
|||||||
TRICK_EXPECT_TRUE( test_so.test_true(), test_suite , "boolean function return" )
|
TRICK_EXPECT_TRUE( test_so.test_true(), test_suite , "boolean function return" )
|
||||||
TRICK_EXPECT_FALSE( test_so.test_false(), test_suite , "boolean function return" )
|
TRICK_EXPECT_FALSE( test_so.test_false(), test_suite , "boolean function return" )
|
||||||
|
|
||||||
|
######################################################################################################################
|
||||||
|
|
||||||
|
test_suite = "SWIG Templates"
|
||||||
|
|
||||||
|
test_so.obj.class_no_ns.tnns.x = 1
|
||||||
|
test_so.obj.class_no_ns.tns.y = 2
|
||||||
|
test_so.obj.class_ns.tnns.x = 3
|
||||||
|
test_so.obj.class_ns.tns.y = 4
|
||||||
|
test_so.obj.foo1.bar.z = 5
|
||||||
|
test_so.obj.foo2.bar.z = 6
|
||||||
|
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.class_no_ns.tnns.x, 1, test_suite , "template member access" )
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.class_no_ns.tns.y, 2, test_suite , "template member access" )
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.class_ns.tnns.x, 3, test_suite , "template member access" )
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.class_ns.tns.y, 4, test_suite , "template member access" )
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.foo1.bar.z, 5, test_suite , "template member access" )
|
||||||
|
TRICK_EXPECT_EQ( test_so.obj.foo2.bar.z, 6, test_suite , "template member access" )
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -28,6 +28,8 @@ LIBRARY DEPENDENCY:
|
|||||||
#include "test_ip/include/NoICG.hh"
|
#include "test_ip/include/NoICG.hh"
|
||||||
#include "exclude_me/include/exclude_me.hh"
|
#include "exclude_me/include/exclude_me.hh"
|
||||||
#include "test_ip/include/Namespace_tests.hh"
|
#include "test_ip/include/Namespace_tests.hh"
|
||||||
|
#include "test_ip/include/TemplateTest.hh"
|
||||||
|
#include "test_ip/include/IfndefSwigTest.hh"
|
||||||
|
|
||||||
/** @class Ball
|
/** @class Ball
|
||||||
@brief ball in C++
|
@brief ball in C++
|
||||||
@ -441,6 +443,12 @@ class ClassOfEverything {
|
|||||||
std::map < std::string , int > msi ;
|
std::map < std::string , int > msi ;
|
||||||
std::list < std::string > ls ;
|
std::list < std::string > ls ;
|
||||||
|
|
||||||
|
ClassNoNS class_no_ns ;
|
||||||
|
NS2::ClassNS class_ns ;
|
||||||
|
|
||||||
|
a::Foo foo1;
|
||||||
|
b::Foo2 foo2;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClassOfEverything (const ClassOfEverything &);
|
ClassOfEverything (const ClassOfEverything &);
|
||||||
ClassOfEverything & operator= (const ClassOfEverything &);
|
ClassOfEverything & operator= (const ClassOfEverything &);
|
||||||
|
35
test/SIM_test_ip/models/test_ip/include/FooB.hh
Normal file
35
test/SIM_test_ip/models/test_ip/include/FooB.hh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/********************************* TRICK HEADER *******************************
|
||||||
|
PURPOSE:
|
||||||
|
()
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
()
|
||||||
|
PROGRAMMERS:
|
||||||
|
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FOOB_HH_
|
||||||
|
#define FOOB_HH_
|
||||||
|
|
||||||
|
namespace FooNamespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// RestartableStateIntegrator
|
||||||
|
template<int T>
|
||||||
|
class FooA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int A = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RestartableFirstOrderODEIntegrator
|
||||||
|
template<int T>
|
||||||
|
class FooB : public FooA<3>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int B = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
test/SIM_test_ip/models/test_ip/include/FooD.hh
Normal file
36
test/SIM_test_ip/models/test_ip/include/FooD.hh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/********************************* TRICK HEADER *******************************
|
||||||
|
PURPOSE:
|
||||||
|
()
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
()
|
||||||
|
PROGRAMMERS:
|
||||||
|
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FOOD_HH_
|
||||||
|
#define FOOD_HH_
|
||||||
|
|
||||||
|
#include "FooB.hh"
|
||||||
|
|
||||||
|
namespace FooNamespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// RestartableSecondOrderODEIntegrator
|
||||||
|
class FooC : public FooA<1>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int C;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RestartableSimpleSecondOrderODEIntegrator
|
||||||
|
template<int T>
|
||||||
|
class FooD : public FooC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int D = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
62
test/SIM_test_ip/models/test_ip/include/IfndefSwigTest.hh
Normal file
62
test/SIM_test_ip/models/test_ip/include/IfndefSwigTest.hh
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/********************************* TRICK HEADER *******************************
|
||||||
|
PURPOSE:
|
||||||
|
()
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
()
|
||||||
|
PROGRAMMERS:
|
||||||
|
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FOO_HH_
|
||||||
|
#define FOO_HH_
|
||||||
|
|
||||||
|
#include "FooB.hh"
|
||||||
|
#include "FooD.hh"
|
||||||
|
|
||||||
|
namespace FooNamespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// RestartableScalarFirstOrderODEIntegrator
|
||||||
|
class FooContB {
|
||||||
|
public:
|
||||||
|
FooContB() : d(12.0) {}
|
||||||
|
|
||||||
|
// RestartableFirstOrderODEIntegrator
|
||||||
|
FooB<2> fooB;
|
||||||
|
|
||||||
|
FooB<2> fooB2;
|
||||||
|
|
||||||
|
double d;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// RestartableT3SecondOrderODEIntegrator
|
||||||
|
class FooContD {
|
||||||
|
public:
|
||||||
|
FooContD() : d(12.0) {}
|
||||||
|
|
||||||
|
// RestartableSimpleSecondOrderODEIntegrator
|
||||||
|
#ifndef TESTING_SWIG
|
||||||
|
# ifndef SWIG
|
||||||
|
// THIS SHOULD PREVENT SWIG FROM MAKING ANY TEMPLATE REFERENCES TO EXCLUDED FooD TYPE
|
||||||
|
FooD<1> fooD;
|
||||||
|
|
||||||
|
FooD<2> fooD2;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int spacer;
|
||||||
|
|
||||||
|
#if ! defined ( SWIG )
|
||||||
|
// THIS SHOULD PREVENT SWIG FROM MAKING ANY TEMPLATE REFERENCES TO EXCLUDED FooD TYPE
|
||||||
|
FooD<3> fooD3;
|
||||||
|
|
||||||
|
FooD<4> fooD4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double d;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -11,10 +11,10 @@ PURPOSE:
|
|||||||
#define TEMPLATETEST_HH
|
#define TEMPLATETEST_HH
|
||||||
|
|
||||||
template <class A, class B>
|
template <class A, class B>
|
||||||
class TTT {
|
class TTT_test {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TTT() {
|
TTT_test() {
|
||||||
aa = 0 ;
|
aa = 0 ;
|
||||||
bb = 0 ;
|
bb = 0 ;
|
||||||
cc = NULL ;
|
cc = NULL ;
|
||||||
@ -22,11 +22,11 @@ class TTT {
|
|||||||
} ;
|
} ;
|
||||||
A aa ;
|
A aa ;
|
||||||
B bb ;
|
B bb ;
|
||||||
TTT<A,B> * ttt ;
|
TTT_test<A,B> * ttt ;
|
||||||
|
|
||||||
typedef TTT<A,B> C ;
|
typedef TTT_test<A,B> C ;
|
||||||
C * cc ;
|
C * cc ;
|
||||||
typedef TTT<B,A> D ;
|
typedef TTT_test<B,A> D ;
|
||||||
D * dd ;
|
D * dd ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ class TemplateTest {
|
|||||||
friend void init_attrTemplateTest() ;
|
friend void init_attrTemplateTest() ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TTT< int , double > TTT_var ;
|
TTT_test< int , double > TTT_var ;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,5 +44,55 @@ class TemplateTest {
|
|||||||
%struct_str(TemplateTest)
|
%struct_str(TemplateTest)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Verify we can build templates/intsantiations defined in different combinations of namespaces
|
||||||
|
template <class T>
|
||||||
|
struct TemplateNoNS {T x;};
|
||||||
|
|
||||||
|
namespace NS1 {
|
||||||
|
template <class T>
|
||||||
|
struct TemplateNS {T y;};
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassNoNS {
|
||||||
|
public:
|
||||||
|
TemplateNoNS<int> tnns;
|
||||||
|
NS1::TemplateNS<int> tns;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace NS2 {
|
||||||
|
class ClassNS {
|
||||||
|
public:
|
||||||
|
TemplateNoNS<int> tnns;
|
||||||
|
NS1::TemplateNS<int> tns;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Verify we can build templates/intsantiations defined in the same namespace
|
||||||
|
namespace a {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Bar {T z;};
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
Bar<int> bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Verify we can build templates/intsantiations defined in different namespaces
|
||||||
|
namespace b {
|
||||||
|
|
||||||
|
class Foo2 {
|
||||||
|
public:
|
||||||
|
a::Bar<int> bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Verify we can build with templated functions (isn't actually SWIG-ified, but should be ignored)
|
||||||
|
template <typename T> void templated_function() {}
|
||||||
|
|
||||||
|
|
||||||
#endif /* _BALL_HH_ */
|
#endif /* _BALL_HH_ */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user