aboutsummaryrefslogtreecommitdiff
path: root/Examples/test-suite/template_partial_specialization_typedef.i
blob: 6fdbf99aa3bda7854325ffbfb14651b0b775bdaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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>;