Updated documentation and testing

This commit is contained in:
Pherring04 2024-06-26 14:08:03 -05:00
parent fa42e8be67
commit 72b3fcaa09
6 changed files with 94 additions and 35 deletions

View File

@ -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,
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
of the specific templated type used by the data member. Add the
SWIG %template directive to the templated typedefs string that
Otherwise append whatever wasn't matched in process contents to
the SWIG interface text.
of the specific templated type used by the data member. Due to changes in SWIG 4,
template directives must be specified before their respective data members. As such,
the template directives are inserted immediately prior to the class definition.
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

View File

@ -646,9 +646,6 @@ sub process_class($$$$$) {
my ($template_type_no_sp) = $template_full_type ;
$template_type_no_sp =~ s/\s//g ;
# If the type is qualified, assume it's fully qualified and put the
# %template directive in the global namespace.
# See https://github.com/nasa/trick/issues/768
#print "*** template_type_no_sp = $template_type_no_sp ***\n" ;
if ( ! exists $processed_templates{$template_type_no_sp} ) {
@ -656,11 +653,16 @@ sub process_class($$$$$) {
my $identifier = "${sanitized_namespace}${class_name}_${var_name}" ;
my $trick_swig_template = "TRICK_SWIG_TEMPLATE_$identifier" ;
# Insert template directive immediately before intsance
# This is required as of SWIG 4
my $typedef = "\n#ifndef $trick_swig_template\n" ;
$typedef .= "#define $trick_swig_template\n" ;
$typedef .= "\%template($identifier) $template_full_type;\n" ;
$typedef .= "#endif\n" ;
# SWIG namespace resolution for template directives starts at the local space
# Therefore, if the type is qualified, assume it's fully qualified and put the
# %template directive in the global namespace by escaping the current namespace
if ($curr_namespace ne "") {
my $in_same_namespace = 1 ;
if ($template_full_type =~ /^\w*(::)\w+</) {
@ -671,7 +673,7 @@ sub process_class($$$$$) {
$typedef = "\n}" . $typedef . "namespace " . $1 . " {" ;
}
}
$template_typedefs .= $typedef ;
$processed_templates{$template_type_no_sp} = 1 ;

View File

@ -2991,6 +2991,24 @@ def main():
TRICK_EXPECT_TRUE( test_so.test_true(), 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__":

View File

@ -28,6 +28,7 @@ LIBRARY DEPENDENCY:
#include "test_ip/include/NoICG.hh"
#include "exclude_me/include/exclude_me.hh"
#include "test_ip/include/Namespace_tests.hh"
#include "test_ip/include/TemplateTest.hh"
/** @class Ball
@brief ball in C++
@ -441,6 +442,12 @@ class ClassOfEverything {
std::map < std::string , int > msi ;
std::list < std::string > ls ;
ClassNoNS class_no_ns ;
NS2::ClassNS class_ns ;
a::Foo foo1;
b::Foo2 foo2;
private:
ClassOfEverything (const ClassOfEverything &);
ClassOfEverything & operator= (const ClassOfEverything &);

View File

@ -15,27 +15,6 @@ PURPOSE:
#include <iostream>
#include <sstream>
template <class T>
class TemplateNoNS {};
class ClassNoNS {
public:
TemplateNoNS<int> tnns;
};
namespace a {
template <class T>
class Bar {};
class Foo {
public:
Bar<int> bar;
};
}
namespace my_ns {
class BB {

View File

@ -11,10 +11,10 @@ PURPOSE:
#define TEMPLATETEST_HH
template <class A, class B>
class TTT {
class TTT_test {
public:
TTT() {
TTT_test() {
aa = 0 ;
bb = 0 ;
cc = NULL ;
@ -22,11 +22,11 @@ class TTT {
} ;
A aa ;
B bb ;
TTT<A,B> * ttt ;
TTT_test<A,B> * ttt ;
typedef TTT<A,B> C ;
typedef TTT_test<A,B> C ;
C * cc ;
typedef TTT<B,A> D ;
typedef TTT_test<B,A> D ;
D * dd ;
} ;
@ -36,7 +36,7 @@ class TemplateTest {
friend void init_attrTemplateTest() ;
public:
TTT< int , double > TTT_var ;
TTT_test< int , double > TTT_var ;
};
@ -44,5 +44,55 @@ class TemplateTest {
%struct_str(TemplateTest)
#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_ */