Fix scoping of forward class declarations nested within a class (for C++). Also fix %template and resolution of template parameters that are typedefs.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12764 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2011-07-26 19:34:23 +00:00
commit 7d038d4bd7
11 changed files with 442 additions and 54 deletions

View file

@ -383,6 +383,7 @@ CPP_TEST_CASES += \
template_tbase_template \
template_template_parameters \
template_typedef \
template_typedef_class_template \
template_typedef_cplx \
template_typedef_cplx2 \
template_typedef_cplx3 \
@ -392,6 +393,9 @@ CPP_TEST_CASES += \
template_typedef_ns \
template_typedef_ptr \
template_typedef_rec \
template_typemaps \
template_typemaps_typedef \
template_typemaps_typedef2 \
template_using \
template_virtual \
template_whitespace \

View file

@ -0,0 +1,37 @@
from template_typemaps_typedef2 import *
m1 = MultimapIntA()
dummy_pair = m1.make_dummy_pair()
val = m1.typemap_test(dummy_pair).val
if val != 1234:
raise RuntimeError, "typemaps not working"
m2 = MultimapAInt()
# TODO: typemaps and specializations not quite working as expected. T needs expanding, but at least the right typemap is being picked up.
#dummy_pair = m2.make_dummy_pair()
#val = m2.typemap_test(dummy_pair)
#print val
#if val != 4321:
# raise RuntimeError, "typemaps not working"
if typedef_test1(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test1 not working"
if typedef_test2(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test2 not working"
if typedef_test3(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test3 not working"
if typedef_test4(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test4 not working"
if typedef_test5(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test5 not working"
if typedef_test6(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test6 not working"

View file

@ -0,0 +1,37 @@
from template_typemaps_typedef import *
m1 = MultimapIntA()
dummy_pair = m1.make_dummy_pair()
val = m1.typemap_test(dummy_pair).val
if val != 1234:
raise RuntimeError, "typemaps not working"
m2 = MultimapAInt()
# TODO: typemaps and specializations not quite working as expected. T needs expanding, but at least the right typemap is being picked up.
#dummy_pair = m2.make_dummy_pair()
#val = m2.typemap_test(dummy_pair)
#print val
#if val != 4321:
# raise RuntimeError, "typemaps not working"
if typedef_test1(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test1 not working"
if typedef_test2(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test2 not working"
if typedef_test3(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test3 not working"
if typedef_test4(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test4 not working"
if typedef_test5(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test5 not working"
if typedef_test6(dummy_pair).val != 1234:
raise RuntimeError, "typedef_test6 not working"

View file

@ -0,0 +1,57 @@
%module template_typedef_class_template
%inline %{
namespace Standard {
template <class T, class U > struct Pair {
T first;
U second;
};
}
%}
// previously these typemaps were erroneously being used as iterator was not correctly scoped in Multimap
%typemap(out) Standard::Pair<Standard::iterator, Standard::iterator> "_this_will_not_compile_iterator_"
%typemap(out) Standard::Pair<Standard::const_iterator, Standard::const_iterator> "_this_will_not_compile_const_iterator_"
%{
namespace Standard {
template<class Key, class T> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator {};
class const_iterator {};
// test usage of a typedef of a nested class in a template
Standard::Pair<iterator,iterator> equal_range_1(const key_type& kt1) {}
Standard::Pair<const_iterator,const_iterator> equal_range_2(const key_type& kt2) const {}
};
}
%}
namespace Standard {
template<class Key, class T> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator;
class const_iterator;
// test usage of a typedef of a nested class in a template
Standard::Pair<iterator,iterator> equal_range_1(const key_type& kt1) {}
Standard::Pair<const_iterator,const_iterator> equal_range_2(const key_type& kt2) const {}
};
}
%inline %{
struct A {
int val;
A(int v = 0): val(v) {}
};
%}
%template(PairA) Standard::Pair<int, A*>;
%template(MultimapA) Standard::Multimap<int, A*>;

View file

@ -0,0 +1,109 @@
%module template_typemaps_typedef
// Similar to template_typedef_class_template
// Testing typemaps of a typedef of a nested class in a template and where the template uses default parameters
%inline %{
namespace Standard {
template <class T, class U > struct Pair {
T first;
U second;
};
}
%}
%{
namespace Standard {
template<class Key, class T, class J = int> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator {
public:
mapped_type mm;
iterator(mapped_type m = mapped_type()) : mm(m) {}
};
mapped_type typemap_test(Standard::Pair<iterator,iterator> pp) { return pp.second.mm; }
Standard::Pair<iterator,iterator>* make_dummy_pair() { return new Standard::Pair<iterator, iterator>(); }
};
}
%}
namespace Standard {
template<class Key, class T, class J = int> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator;
%typemap(in) Standard::Pair<iterator,iterator> "$1 = default_general< Key, T >();"
mapped_type typemap_test(Standard::Pair<iterator,iterator> pii1);
Standard::Pair<iterator,iterator>* make_dummy_pair();
};
}
// specialization
namespace Standard {
template<> class Multimap<A, int> {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator;
// Note uses a different function to the non-specialized version
%typemap(in) Standard::Pair<iterator,iterator> "$1 = default_A_int< A, int >();"
mapped_type typemap_test(Standard::Pair<iterator,iterator> pii2);
Standard::Pair<iterator,iterator>* make_dummy_pair();
};
}
%inline %{
struct A {
int val;
A(int v = 0): val(v) {}
};
%}
%{
// For < int, A >
template<typename Key, typename T> Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_general() {
Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_value;
default_value.second.mm = A(1234);
return default_value;
}
// For < A, int >
template<typename Key, typename T> Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_A_int() {
Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_value;
default_value.second.mm = 4321;
return default_value;
}
%}
%inline %{
typedef A AA;
namespace Space {
typedef AA AB;
}
%}
%template(PairIntA) Standard::Pair<int, A>;
%template(MultimapIntA) Standard::Multimap<int, A>;
%template(PairAInt) Standard::Pair<A, int>;
%template(MultimapAInt) Standard::Multimap<A, int>;
%inline %{
// Extend the test with some typedefs in the template parameters
Standard::Multimap< int, AA >::mapped_type typedef_test1(Standard::Pair< Standard::Multimap< int, AA >::iterator, Standard::Multimap< int, AA >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, A >::mapped_type typedef_test2(Standard::Pair< Standard::Multimap< int, A >::iterator, Standard::Multimap< int, A >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, AA, int >::mapped_type typedef_test3(Standard::Pair< Standard::Multimap< int, AA, int >::iterator, Standard::Multimap< int, AA, int >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, A , int >::mapped_type typedef_test4(Standard::Pair< Standard::Multimap< int, A , int >::iterator, Standard::Multimap< int, A , int >::iterator > pp) { return pp.second.mm; }
using namespace Space;
Standard::Multimap< int, AB >::mapped_type typedef_test5(Standard::Pair< Standard::Multimap< int, AB >::iterator, Standard::Multimap< int, AB >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, AB, int >::mapped_type typedef_test6(Standard::Pair< Standard::Multimap< int, AB, int >::iterator, Standard::Multimap< int, AB, int >::iterator > pp) { return pp.second.mm; }
%}

View file

@ -0,0 +1,111 @@
%module template_typemaps_typedef2
// Identical to template_typemaps_typedef, except for %template
// Similar to template_typedef_class_template
// Testing typemaps of a typedef of a nested class in a template and where the template uses default parameters
%inline %{
namespace Standard {
template <class T, class U > struct Pair {
T first;
U second;
};
}
%}
%{
namespace Standard {
template<class Key, class T, class J = int> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator {
public:
mapped_type mm;
iterator(mapped_type m = mapped_type()) : mm(m) {}
};
mapped_type typemap_test(Standard::Pair<iterator,iterator> pp) { return pp.second.mm; }
Standard::Pair<iterator,iterator>* make_dummy_pair() { return new Standard::Pair<iterator, iterator>(); }
};
}
%}
namespace Standard {
template<class Key, class T, class J = int> class Multimap {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator;
%typemap(in) Standard::Pair<iterator,iterator> "$1 = default_general< Key, T >();"
mapped_type typemap_test(Standard::Pair<iterator,iterator> pii1);
Standard::Pair<iterator,iterator>* make_dummy_pair();
};
}
// specialization
namespace Standard {
template<> class Multimap<A, int> {
public:
typedef Key key_type;
typedef T mapped_type;
class iterator;
// Note uses a different function to the non-specialized version
%typemap(in) Standard::Pair<iterator,iterator> "$1 = default_A_int< A, int >();"
mapped_type typemap_test(Standard::Pair<iterator,iterator> pii2);
Standard::Pair<iterator,iterator>* make_dummy_pair();
};
}
%inline %{
struct A {
int val;
A(int v = 0): val(v) {}
};
%}
%{
// For < int, A >
template<typename Key, typename T> Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_general() {
Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_value;
default_value.second.mm = A(1234);
return default_value;
}
// For < A, int >
template<typename Key, typename T> Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_A_int() {
Standard::Pair< typename Standard::Multimap< Key, T >::iterator, typename Standard::Multimap< Key, T >::iterator > default_value;
default_value.second.mm = 4321;
return default_value;
}
%}
%inline %{
typedef A AA;
namespace Space {
typedef AA AB;
}
%}
%template(PairIntA) Standard::Pair<int, Space::AB>;
%template(MultimapIntA) Standard::Multimap<int, Space::AB>;
%template(PairAInt) Standard::Pair<Space::AB, int>;
%template(MultimapAInt) Standard::Multimap<Space::AB, int>;
%inline %{
// Extend the test with some typedefs in the template parameters
Standard::Multimap< int, AA >::mapped_type typedef_test1(Standard::Pair< Standard::Multimap< int, AA >::iterator, Standard::Multimap< int, AA >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, A >::mapped_type typedef_test2(Standard::Pair< Standard::Multimap< int, A >::iterator, Standard::Multimap< int, A >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, AA, int >::mapped_type typedef_test3(Standard::Pair< Standard::Multimap< int, AA, int >::iterator, Standard::Multimap< int, AA, int >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, A , int >::mapped_type typedef_test4(Standard::Pair< Standard::Multimap< int, A , int >::iterator, Standard::Multimap< int, A , int >::iterator > pp) { return pp.second.mm; }
using namespace Space;
Standard::Multimap< int, AB >::mapped_type typedef_test5(Standard::Pair< Standard::Multimap< int, AB >::iterator, Standard::Multimap< int, AB >::iterator > pp) { return pp.second.mm; }
Standard::Multimap< int, AB, int >::mapped_type typedef_test6(Standard::Pair< Standard::Multimap< int, AB, int >::iterator, Standard::Multimap< int, AB, int >::iterator > pp) { return pp.second.mm; }
%}