Fix partial specialization and explicit specialization lookup

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11703 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2009-10-20 17:50:36 +00:00
commit 4b2ced5095
8 changed files with 784 additions and 152 deletions

View file

@ -339,6 +339,8 @@ CPP_TEST_CASES += \
template_ns_inherit \
template_ns_scope \
template_partial_arg \
template_partial_specialization \
template_partial_specialization_typedef \
template_qualifier \
template_qualifier \
template_ref_type \

View file

@ -0,0 +1,59 @@
import template_partial_specialization.*;
public class template_partial_specialization_runme {
static {
try {
System.loadLibrary("template_partial_specialization");
} 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[]) {
// One parameter tests
new A().a();
new B().b();
new C().c();
new D().d();
new E().e();
new F().f();
new G().g();
new H().h();
new I().i();
new J().j();
new K().k();
new L().l();
new BB().b();
new BBB().b();
new BBBB().b();
new BBBBB().b();
new B1().b();
new B2().b();
new B3().b();
new B4().b();
// Two parameter tests
new A_().a();
new B_().b();
new C_().c();
new D_().d();
new E_().e();
new F_().f();
new G_().g();
new C1_().c();
new C2_().c();
new C3_().c();
new C4_().c();
new B1_().b();
new E1_().e();
new E2_().e();
}
}

View file

@ -0,0 +1,59 @@
import template_partial_specialization_typedef.*;
public class template_partial_specialization_typedef_runme {
static {
try {
System.loadLibrary("template_partial_specialization_typedef");
} 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[]) {
// One parameter tests
new A().a();
new B().b();
new C().c();
new D().d();
new E().e();
new F().f();
new G().g();
new H().h();
new I().i();
new J().j();
new K().k();
new L().l();
new BB().b();
new BBB().b();
new BBBB().b();
new BBBBB().b();
new B1().b();
new B2().b();
new B3().b();
new B4().b();
// Two parameter tests
new A_().a();
new B_().b();
new C_().c();
new D_().d();
new E_().e();
new F_().f();
new G_().g();
new C1_().c();
new C2_().c();
new C3_().c();
new C4_().c();
new B1_().b();
new E1_().e();
new E2_().e();
}
}

View file

@ -0,0 +1,134 @@
%module template_partial_specialization
%inline %{
namespace One {
template <typename T> struct OneParm { void a() {} };
template <typename T> struct OneParm<T *> { void b() {} };
template <typename T> struct OneParm<T &> { void c() {} };
template <typename T> struct OneParm<T const &> { void d() {} };
template <typename T> struct OneParm<T * const &> { void e() {} };
template <> struct OneParm<int> { void f() {} };
template <> struct OneParm<int * const &> { void g() {} };
template <> struct OneParm<int **> { void h() {} };
template <> struct OneParm<float> { void i() {} };
template <> struct OneParm<float *> { void j() {} };
template <> struct OneParm<float **> { void k() {} };
template <> struct OneParm<float ***> { void l() {} };
}
%}
// partial specializations
%template(A) One::OneParm<double>;
%template(B) One::OneParm<double *>;
%template(C) One::OneParm<double &>;
%template(D) One::OneParm<const double &>;
%template(E) One::OneParm<double * const &>;
// explicit specializations
%template(F) One::OneParm<int>;
%template(G) One::OneParm<int * const &>;
%template(H) One::OneParm<int **>;
// %template scope explicit specializations
namespace ONE {
%template(I) One::OneParm<float>;
%template(J) ::One::OneParm<float *>;
}
%template(K) ::One::OneParm<float **>;
namespace One {
%template(L) OneParm<float ***>;
}
// %template scope partial specializations
namespace ONE {
%template(BB) One::OneParm<bool *>;
%template(BBB) ::One::OneParm<char *>;
}
%template(BBBB) ::One::OneParm<short *>;
namespace One {
%template(BBBBB) OneParm<long *>;
}
// non-exact match
%template(B1) One::OneParm<unsigned int **>;
%template(B2) One::OneParm<unsigned int ***>;
%template(B3) One::OneParm<const unsigned int *>;
%template(B4) One::OneParm<const unsigned int **>;
// Two parameter specialization tests
%inline %{
struct Concrete {};
namespace Two {
template <typename T1, typename T2> struct TwoParm { void a() {} };
template <typename T1, typename T2> struct TwoParm<T1 *, T2 *> { void b() {} };
template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *> { void c() {} };
template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *> { void d() {} };
template <typename T1> struct TwoParm<T1 *, int *> { void e() {} };
template <typename T1> struct TwoParm<T1, int> { void f() {} };
template <> struct TwoParm<int *, const int *> { void g() {} };
}
%}
namespace Two {
%template(A_) TwoParm<double, double>;
%template(B_) TwoParm<double *, double *>;
%template(C_) TwoParm<double *, const double *>;
%template(D_) TwoParm<const int *, const int *>;
%template(E_) TwoParm<int *, int *>;
%template(F_) TwoParm<int *, int>;
%template(G_) TwoParm<int *, const int *>;
%template(C1_) TwoParm<Concrete *, const Concrete *>;
%template(C2_) TwoParm<int *, const ::Concrete *>;
}
%template(C3_) Two::TwoParm<double *, const ::Concrete *>;
%template(C4_) ::Two::TwoParm<void *, const ::Concrete *>;
%template(B1_) ::Two::TwoParm<char *, ::Concrete *>;
%template(E1_) Two::TwoParm<const int *, int *>;
%template(E2_) Two::TwoParm<int **, int *>;
#if 0
// TODO fix:
%inline %{
//namespace S {
template<typename T> struct X { void a() {} };
template<typename T> struct X<T *> { void b() {} };
// template<> struct X<int *> { void c() {} };
//}
%}
#if 0
struct AA { // crashes
#else
namespace AA { // thinks X is in AA namespace
%template(X2) X<int *>;
};
#endif
#endif
#if 0
namespace Space {
}
template<typename T> struct Vector {
#ifdef SWIG
%template() Space::VectorHelper<T>;
#endif
void gook(T i) {}
void geeko(double d) {}
void geeky(int d) {}
};
/*
template<typename T> struct Vector<T *> {
};
*/
//}
%}
%template(VectorIntPtr) Space::Vector<int *>; // should fail as Vector is in global namespace
// is this a regression - no fails in 1.3.40 too
// Note problem is removed by removing empty Space namespace!!
#endif

View file

@ -0,0 +1,130 @@
// This testcase is almost identical to template_partial_specialization but uses typedefs for %template
%module template_partial_specialization_typedef
%inline %{
namespace TypeDef {
typedef double Double;
typedef int * IntPtr;
typedef double * DoublePtr;
typedef double & DoubleRef;
typedef const double & ConstDoubleRef;
typedef double * const & DoublePtrConstRef;
typedef int Int;
typedef int * const & IntPtrConstRef;
typedef int ** IntPtrPtr;
typedef float Float;
typedef float * FloatPtr;
typedef float ** FloatPtrPtr;
typedef float *** FloatPtrPtrPtr;
typedef bool * BoolPtr;
typedef char * CharPtr;
typedef short * ShortPtr;
typedef long * LongPtr;
typedef unsigned int ** UnsignedIntPtrPtr;
typedef unsigned int *** UnsignedIntPtrPtrPtr;
typedef const unsigned int ** ConstUnsignedIntPtr;
typedef const unsigned int *** ConstUnsignedIntPtrPtr;
}
namespace One {
template <typename T> struct OneParm { void a() {} };
template <typename T> struct OneParm<T *> { void b() {} };
template <typename T> struct OneParm<T &> { void c() {} };
template <typename T> struct OneParm<T const &> { void d() {} };
template <typename T> struct OneParm<T * const &> { void e() {} };
template <> struct OneParm<int> { void f() {} };
template <> struct OneParm<int * const &> { void g() {} };
template <> struct OneParm<int **> { void h() {} };
template <> struct OneParm<float> { void i() {} };
template <> struct OneParm<float *> { void j() {} };
template <> struct OneParm<float **> { void k() {} };
template <> struct OneParm<float ***> { void l() {} };
}
%}
// partial specializations
%template(A) One::OneParm<TypeDef::Double>;
%template(B) One::OneParm<TypeDef::DoublePtr>;
%template(C) One::OneParm<TypeDef::DoubleRef>;
%template(D) One::OneParm<TypeDef::ConstDoubleRef>;
%template(E) One::OneParm<TypeDef::DoublePtrConstRef>;
// explicit specializations
%template(F) One::OneParm<TypeDef::Int>;
%template(G) One::OneParm<TypeDef::IntPtrConstRef>;
%template(H) One::OneParm<TypeDef::IntPtrPtr>;
// %template scope explicit specializations
namespace ONE {
%template(I) One::OneParm<TypeDef::Float>;
%template(J) ::One::OneParm<TypeDef::FloatPtr>;
}
%template(K) ::One::OneParm<TypeDef::FloatPtrPtr>;
namespace One {
%template(L) OneParm<TypeDef::FloatPtrPtrPtr>;
}
// %template scope partial specializations
namespace ONE {
%template(BB) One::OneParm<TypeDef::BoolPtr>;
%template(BBB) ::One::OneParm<TypeDef::CharPtr>;
}
%template(BBBB) ::One::OneParm<TypeDef::ShortPtr>;
namespace One {
%template(BBBBB) OneParm<TypeDef::LongPtr>;
}
// non-exact match
%template(B1) One::OneParm<TypeDef::UnsignedIntPtrPtr>;
%template(B2) One::OneParm<TypeDef::UnsignedIntPtrPtrPtr>;
%template(B3) One::OneParm<TypeDef::ConstUnsignedIntPtr>;
%template(B4) One::OneParm<TypeDef::ConstUnsignedIntPtrPtr>;
// Two parameter specialization tests
%inline %{
struct Concrete {};
namespace Two {
template <typename T1, typename T2> struct TwoParm { void a() {} };
template <typename T1, typename T2> struct TwoParm<T1 *, T2 *> { void b() {} };
template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *> { void c() {} };
template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *> { void d() {} };
template <typename T1> struct TwoParm<T1 *, int *> { void e() {} };
template <typename T1> struct TwoParm<T1, int> { void f() {} };
template <> struct TwoParm<int *, const int *> { void g() {} };
}
%}
%inline %{
namespace TypeDef {
typedef const double * ConstDoublePtr;
typedef const int * ConstIntPtr;
typedef int * IntPtr;
typedef Concrete * ConcretePtr;
typedef const Concrete * ConstConcretePtr;
typedef void * VoidPtr;
}
%}
namespace Two {
%template(A_) TwoParm<TypeDef::Double, TypeDef::Double>;
%template(B_) TwoParm<TypeDef::DoublePtr, TypeDef::DoublePtr>;
%template(C_) TwoParm<TypeDef::DoublePtr, TypeDef::ConstDoublePtr>;
%template(D_) TwoParm<TypeDef::ConstIntPtr, TypeDef::ConstIntPtr>;
%template(E_) TwoParm<TypeDef::IntPtr, TypeDef::IntPtr>;
%template(F_) TwoParm<TypeDef::IntPtr, TypeDef::Int>;
%template(G_) TwoParm<TypeDef::IntPtr, TypeDef::ConstIntPtr>;
%template(C1_) TwoParm<TypeDef::ConcretePtr, TypeDef::ConstConcretePtr>;
%template(C2_) TwoParm<TypeDef::IntPtr, TypeDef::ConstConcretePtr>;
}
%template(C3_) Two::TwoParm<TypeDef::DoublePtr, TypeDef::ConstConcretePtr>;
%template(C4_) ::Two::TwoParm<TypeDef::VoidPtr, TypeDef::ConstConcretePtr>;
%template(B1_) ::Two::TwoParm<TypeDef::CharPtr, TypeDef::ConcretePtr>;
%template(E1_) Two::TwoParm<TypeDef::ConstIntPtr, TypeDef::IntPtr>;
%template(E2_) Two::TwoParm<TypeDef::IntPtrPtr, TypeDef::IntPtr>;