import source from 1.3.40
[external/swig.git] / Examples / test-suite / special_variable_macros.i
1 %module special_variable_macros
2
3 // test $typemap() special variable function
4 // these tests are not typical of how $typemap() should be used, but it checks that it is mostly working
5
6 %inline %{
7 struct Name {
8   Name(const char *n="none") : name(n) {}
9   const char *getName() const { return name; };
10   Name *getNamePtr() { return this; };
11 private:
12   const char *name;
13 };
14 struct NameWrap {
15   NameWrap(const char *n="casternone") : name(n) {}
16   Name *getNamePtr() { return &name; };
17 private:
18   Name name;
19 };
20 %}
21
22 // check $1 and $input get expanded properly when used from $typemap()
23 %typemap(in) Name *GENERIC ($*1_type temp)
24 %{
25   /*%typemap(in) Name *GENERIC start */
26   temp = Name("$specialname");
27   (void)$input;
28   $1 = ($1_ltype) &temp;
29   /*%typemap(in) Name *GENERIC end */
30 %}
31
32 // This would never be done in real code, it is just a test of what madness can be done.
33 // Note that the special variable substitutions $*1_type, $descriptor etc are for NameWrap 
34 // even when used within the Name typemap via $typemap. I can't think of any useful use cases
35 // for this behaviour in the C/C++ typemaps, but it is possible.
36 %typemap(in) NameWrap *NAMEWRAP ($*1_type temp)
37 %{
38   /*%typemap(in) NameWrap *NAMEWRAP start */
39   temp = $*1_ltype("$descriptor");
40   (void)$input;
41   $1 = temp.getNamePtr();
42   /*%typemap(in) NameWrap *NAMEWRAP end */
43 %}
44
45
46 //////////////////////////////////////////////////////////////////////////////////////
47
48 // This should use Name *GENERIC typemap which ignores passed in Name * and instead uses a newly a newly constructed Name
49 // held in a typemap variable with name="$specialname"
50 %typemap(in) Name *jack {
51 // %typemap(in) Name *jack start
52 $typemap(in, Name *GENERIC)
53 // %typemap(in) Name *jack end
54 }
55
56 // as above, but also perform variable substitution
57 %typemap(in) Name *jill {
58 // %typemap(in) Name *jill start
59 $typemap(in, Name *GENERIC, specialname=jilly)
60 // %typemap(in) Name *jill end
61 }
62
63 %typemap(in) Name *mary {
64 // %typemap(in) Name *mary start
65 $typemap(in, NameWrap *NAMEWRAP)
66 // %typemap(in) Name *mary end
67 }
68
69 %inline %{
70 const char * testFred(Name *fred) {
71   return fred->getName();
72 }
73 const char * testJack(Name *jack) {
74   return jack->getName();
75 }
76 const char * testJill(Name *jill) {
77   return jill->getName();
78 }
79 const char * testMary(Name *mary) {
80   return mary->getName();
81 }
82 %}
83
84 //////////////////////////////////////////////////////////////////////////////////////
85 // Multi-arg typemap lookup
86 // One would never do something like this in reality, it just checks $typemap with multi-arg typemaps
87 %typemap(in) (Name *multiname, int num)($*1_type temp_name, $2_ltype temp_count)
88 %{
89   /*%typemap(in) (Name *multiname, int num) start */
90   temp_name = $*1_ltype("multiname num");
91   temp_count = (int)strlen(temp_name.getNamePtr()->getName());
92   (void)$input;
93   $1 = temp_name.getNamePtr();
94   $2 = temp_count + 100;
95   /*%typemap(in) (Name *multiname, int num) end */
96 %}
97
98 %typemap(in) (Name *jim, int count) {
99 // %typemap(in) Name *jim start
100 $typemap(in, (Name *multiname, int num))
101 // %typemap(in) Name *jim end
102 }
103
104 %inline %{
105 const char * testJim(Name *jim, int count) {
106   if (count != (int)strlen(jim->getNamePtr()->getName()) + 100)
107     return "size check failed";
108   else
109     return jim->getName();
110 }
111 %}
112
113 //////////////////////////////////////////////////////////////////////////////////////
114 // Template types with more than one template parameter
115
116 // check $1 and $input get expanded properly when used from $typemap()
117 %typemap(in) Space::Pair<int, bool> PAIR_INT_BOOL ($1_type temp)
118 %{
119   /*%typemap(in) Name *GENERIC start */
120   temp = Space::Pair<int, bool>(123, true);
121   (void)$input;
122   $1 = ($1_ltype)temp;
123   /*%typemap(in) Name *GENERIC end */
124 %}
125
126 %typemap(in) Space::Pair<int, bool> john {
127 // %typemap(in) Name *john start
128 $typemap(in, Space::Pair<int, bool> PAIR_INT_BOOL)
129 // %typemap(in) Name *john end
130 }
131
132 %inline %{
133 namespace Space {
134   template <typename T1, typename T2> struct Pair {
135     Pair(T1 f, T2 s) : first(f), second(s) {}
136     Pair() {}
137     T1 first;
138     T2 second;
139   };
140   int testJohn(Space::Pair<int, bool> john) {
141     return john.first;
142   }
143 }
144 %}
145 %template(PairIntBool) Space::Pair<int, bool>;
146
147 //////////////////////////////////////////////////////////////////////////////////////
148 // A real use case for $typemap
149
150 #if defined(SWIGCSHARP)
151 %typemap(cscode) Space::RenameMe %{
152   public static NewName factory(String s) {
153   //below should expand to:
154   //return new NewName( new Name(s) );
155     return new $typemap(cstype, Space::RenameMe)( new $typemap(cstype, Name)(s) ); 
156   }
157 %}
158 #elif defined(SWIGJAVA)
159 %typemap(javacode) Space::RenameMe %{
160   public static NewName factory(String s) {
161   //below should expand to:
162   //return new NewName( new Name(s) );
163     return new $typemap(jstype, Space::RenameMe)( new $typemap(jstype, Name)(s) ); 
164   }
165 %}
166 #endif
167
168 %rename(NewName) Space::RenameMe;
169 %inline %{
170 namespace Space {
171   struct RenameMe {
172     RenameMe(Name n) : storedName(n) {}
173     Name getStoredName() { return storedName; }
174   private:
175     Name storedName;
176   };
177 }
178 %}
179