MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
jtie_gcalls.hpp
1 /*
2  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 /*
18  * jtie_gcalls.hpp
19  */
20 
21 #ifndef jtie_gcalls_hpp
22 #define jtie_gcalls_hpp
23 
24 #include "jtie_stdint.h"
25 #include "jtie_tconv_impl.hpp"
26 #include "jtie_tconv_object_impl.hpp"
27 #include "helpers.hpp"
28 
29 // ---------------------------------------------------------------------------
30 // generic wrapper function definitions
31 // ---------------------------------------------------------------------------
32 
33 // XXX document workaround for MSVC's problems with template disambiguation:
34 // gcall -> gcall_fr, gcall_fv, gcall_mfr, gcall_mfv
35 
36 // XXX update comments below on alternate handling of const member functions
37 
38 // Design and Implementation Notes:
39 //
40 // - The function templates (gcall<...>() et al) in this file implement
41 // generically the delegation of Java method calls to C++ functions.
42 //
43 // While the template definitions are schematic, they are quite numerous.
44 // For example, to support up to 10-ary functions, 60 + 6 + 1 = 67 wrapper
45 // template definitions need to written (plus 11 + 1 for c'tor, d'tor).
46 //
47 // Therefore, preprocessor macros are used below for generating the
48 // n-ary template definitions allowing for drastically cutting down the
49 // code to the basic patterns -- at the expense of readability, however.
50 //
51 // - The templates' type parameters allow to abstract from the formal types
52 // of parameters, result, and object invocation target. The diverse data
53 // conversions between the actual Java and C++ parameters are carried out
54 // by the classes Param<>, Result<>, and Target<>, respectively.
55 //
56 // - In contrast, it's more difficult to abstract from the number of
57 // parameters using templates for maximum compile-time computation.
58 // Other options:
59 // - variadic templates: not in the C++ standard yet
60 // - using template tuple (or recursive list) types to assemble the call
61 // arguments into a single compile-time data structure: poses code upon
62 // the caller, especially, when having to specify the full signature
63 // of the C function as template arguments
64 //
65 // - In addition, by the C++ rules on matching formal and actual template
66 // paramters for function types, *six* separate, "overloaded" definitions
67 // are needed for each n-ary wrapper function template:
68 //
69 // Category: Template Parameter Signature:
70 // 1 global functions
71 // 1.1 w/o return: void F(...)
72 // 1.2 w/ return: RT::CF_t F(...)
73 // 2 static member functions
74 // 2.1 w/o return: same as 1.1
75 // 2.2 w/ return: same as 1.2
76 // 3 non-static member functions
77 // 3.1 non-const member
78 // 3.1.1 w/o return: void (OT::CF_t::*F)(...)
79 // 3.1.2 w/ return: RT::CF_t (OT::CF_t::*F)(...)
80 // 3.2 const member
81 // 3.2.1 w/o return: void (OT::CF_t::*F)(...) const
82 // 3.2.2 w/ return: RT::CF_t (OT::CF_t::*F)(...) const
83 //
84 // Other options:
85 // - 'void' can be used as argument for a formal template type parameter,
86 // collapsing the const/non-const patterns: works only in simple cases,
87 // not with code/return stmts for Java-C++ parameter/result conversions
88 //
89 // - Introduce a C function call wrapper class templates that abstract from
90 // the signature differences hiding them from the gcall<...>() functions:
91 // poses code upon the caller to construct the C call wrapper type with
92 // the list all the C function's return/parameter types.
93 //
94 // - Target objects are internally (OT::CA_t) hold by reference (they must
95 // not be null, which Target<> checks during JA_t -> CA_t conversion).
96 // Hence, the code below applies a pointer-to-function-member
97 // (cao.*F)() -- on object
98 // [(cao->*F)() -- on pointer-to-object, if held as pointer]
99 //
100 // - One must be careful not to trigger any copy-constructing at explicit
101 // type casts between an object (result) from the C formal to the actual
102 // type (e.g., A & -> A) using the cast<> function template, e.g.:
103 // cast< typename OT::CF_t, typename OT::CA_t >(cao)
104 // cast< typename P0T::CF_t, typename P0T::CA_t >(cap0)
105 // ...
106 //
107 // However, this issue is moot now, since all casts between the formal
108 // and actual C types were removed under the requirement that these types
109 // have to be assignment compatible.
110 //
111 // An application is not affected when using the mapping as generated
112 // by the pre-defined macro
113 // define_class_mapping( J, C )
114 // for user-defined classes.
115 //
116 // - Generic wrapper functions gcreate<>() and gdelete<>() are provided that
117 // allow calling C++ constructors and destructors. Unlike the gcall<>()
118 // wrapper function template, the gcreate/gdelete do not take the name of
119 // a C++ function as template parameter, since constructors/destructors
120 // do not have a (member) name and cannot be passed as template arguments.
121 //
122 // To be able to invoke and map to constructors/destructors through the
123 // same framework used for ordinary functions, internal low-level wrapper
124 // class templates ConstructorX/Destructor are defined with raw C++
125 // arguments/results, to which gcreate<>() and gdelete<>() delegate.
126 // (Cannot use function templates here, for need of partial specialization.)
127 //
128 // The internal ConstructorX/Destructor wrappers provide the result or
129 // parameter as both, reference or pointer types.
130 //
131 // This way, the application can choose between a reference or pointer
132 // type mapping of the result/parameter (reference conversion checking
133 // for NULL and rasing a proper Java exception).
134 
135 // ---------------------------------------------------------------------------
136 // List Generation Macros
137 // ---------------------------------------------------------------------------
138 
139 // a macro used as element in a list; the argument is expanded, e.g.
140 // #define MY_MACRO(n) a##n
141 // LE(MY_MACRO(3)) --> a3
142 #define LE(x) x
143 
144 // a macro generating a blank-separated list
145 //
146 // usage: pass the name of a macro taking a number argument, e.g.
147 // #define MY_MACRO(n) a##n
148 // BSL0(MY_MACRO) -->
149 // BSL1(MY_MACRO) --> a1
150 // BSL2(MY_MACRO) --> a1 a2
151 #define BSL0(m)
152 #define BSL1(m) LE(m(1))
153 #define BSL2(m) BSL1(m) LE(m(2))
154 #define BSL3(m) BSL2(m) LE(m(3))
155 #define BSL4(m) BSL3(m) LE(m(4))
156 #define BSL5(m) BSL4(m) LE(m(5))
157 #define BSL6(m) BSL5(m) LE(m(6))
158 #define BSL7(m) BSL6(m) LE(m(7))
159 #define BSL8(m) BSL7(m) LE(m(8))
160 #define BSL9(m) BSL8(m) LE(m(9))
161 #define BSL10(m) BSL9(m) LE(m(10))
162 #define BSL11(m) BSL10(m) LE(m(11))
163 #define BSL12(m) BSL11(m) LE(m(12))
164 #define BSL13(m) BSL12(m) LE(m(13))
165 #define BSL14(m) BSL13(m) LE(m(14))
166 #define BSL15(m) BSL14(m) LE(m(15))
167 #define BSL16(m) BSL15(m) LE(m(16))
168 #define BSL17(m) BSL16(m) LE(m(17))
169 #define BSL18(m) BSL17(m) LE(m(18))
170 #define BSL19(m) BSL18(m) LE(m(19))
171 
172 // a macro generating a blank-separated list in reverse order
173 //
174 // usage: pass the name of a macro taking a number argument, e.g.
175 // #define MY_MACRO(n) a##n
176 // RBSL0(MY_MACRO) -->
177 // RBSL1(MY_MACRO) --> a1
178 // RBSL2(MY_MACRO) --> a2 a1
179 #define RBSL0(m)
180 #define RBSL1(m) LE(m(1))
181 #define RBSL2(m) LE(m(2)) RBSL1(m)
182 #define RBSL3(m) LE(m(3)) RBSL2(m)
183 #define RBSL4(m) LE(m(4)) RBSL3(m)
184 #define RBSL5(m) LE(m(5)) RBSL4(m)
185 #define RBSL6(m) LE(m(6)) RBSL5(m)
186 #define RBSL7(m) LE(m(7)) RBSL6(m)
187 #define RBSL8(m) LE(m(8)) RBSL7(m)
188 #define RBSL9(m) LE(m(9)) RBSL8(m)
189 #define RBSL10(m) LE(m(10)) RBSL9(m)
190 #define RBSL11(m) LE(m(11)) RBSL10(m)
191 #define RBSL12(m) LE(m(12)) RBSL11(m)
192 #define RBSL13(m) LE(m(13)) RBSL12(m)
193 #define RBSL14(m) LE(m(14)) RBSL13(m)
194 #define RBSL15(m) LE(m(15)) RBSL14(m)
195 #define RBSL16(m) LE(m(16)) RBSL15(m)
196 #define RBSL17(m) LE(m(17)) RBSL16(m)
197 #define RBSL18(m) LE(m(18)) RBSL17(m)
198 #define RBSL19(m) LE(m(19)) RBSL18(m)
199 
200 // a macro generating a comma-separated list
201 //
202 // usage: pass the name of a macro taking a number argument, e.g.
203 // #define MY_MACRO(n) a##n
204 // CSL0(MY_MACRO) -->
205 // CSL1(MY_MACRO) --> a1
206 // CSL2(MY_MACRO) --> a1, a2
207 #define CSL0(m)
208 #define CSL1(m) LE(m(1))
209 #define CSL2(m) CSL1(m), LE(m(2))
210 #define CSL3(m) CSL2(m), LE(m(3))
211 #define CSL4(m) CSL3(m), LE(m(4))
212 #define CSL5(m) CSL4(m), LE(m(5))
213 #define CSL6(m) CSL5(m), LE(m(6))
214 #define CSL7(m) CSL6(m), LE(m(7))
215 #define CSL8(m) CSL7(m), LE(m(8))
216 #define CSL9(m) CSL8(m), LE(m(9))
217 #define CSL10(m) CSL9(m), LE(m(10))
218 #define CSL11(m) CSL10(m), LE(m(11))
219 #define CSL12(m) CSL11(m), LE(m(12))
220 #define CSL13(m) CSL12(m), LE(m(13))
221 #define CSL14(m) CSL13(m), LE(m(14))
222 #define CSL15(m) CSL14(m), LE(m(15))
223 #define CSL16(m) CSL15(m), LE(m(16))
224 #define CSL17(m) CSL16(m), LE(m(17))
225 #define CSL18(m) CSL17(m), LE(m(18))
226 #define CSL19(m) CSL18(m), LE(m(19))
227 
228 // a macro generating a comma-preceded list
229 //
230 // usage: pass the name of a macro taking a number argument, e.g.
231 // #define MY_MACRO(n) a##n
232 // CPL0(MY_MACRO) -->
233 // CPL1(MY_MACRO) --> ,a1
234 // CPL2(MY_MACRO) --> ,a1 ,a2
235 #define CPL0(m)
236 #define CPL1(m) ,LE(m(1))
237 #define CPL2(m) CPL1(m) ,LE(m(2))
238 #define CPL3(m) CPL2(m) ,LE(m(3))
239 #define CPL4(m) CPL3(m) ,LE(m(4))
240 #define CPL5(m) CPL4(m) ,LE(m(5))
241 #define CPL6(m) CPL5(m) ,LE(m(6))
242 #define CPL7(m) CPL6(m) ,LE(m(7))
243 #define CPL8(m) CPL7(m) ,LE(m(8))
244 #define CPL9(m) CPL8(m) ,LE(m(9))
245 #define CPL10(m) CPL9(m) ,LE(m(10))
246 #define CPL11(m) CPL10(m) ,LE(m(11))
247 #define CPL12(m) CPL11(m) ,LE(m(12))
248 #define CPL13(m) CPL12(m) ,LE(m(13))
249 #define CPL14(m) CPL13(m) ,LE(m(14))
250 #define CPL15(m) CPL14(m) ,LE(m(15))
251 #define CPL16(m) CPL15(m) ,LE(m(16))
252 #define CPL17(m) CPL16(m) ,LE(m(17))
253 #define CPL18(m) CPL17(m) ,LE(m(18))
254 #define CPL19(m) CPL18(m) ,LE(m(19))
255 
256 // a macro generating a comma-terminated list
257 //
258 // usage: pass the name of a macro taking a number argument, e.g.
259 // #define MY_MACRO(n) a##n
260 // CTL0(MY_MACRO) -->
261 // CTL1(MY_MACRO) --> a1,
262 // CTL2(MY_MACRO) --> a1, a2,
263 #define CTL0(m)
264 #define CTL1(m) LE(m(1)),
265 #define CTL2(m) CTL1(m) LE(m(2)),
266 #define CTL3(m) CTL2(m) LE(m(3)),
267 #define CTL4(m) CTL3(m) LE(m(4)),
268 #define CTL5(m) CTL4(m) LE(m(5)),
269 #define CTL6(m) CTL5(m) LE(m(6)),
270 #define CTL7(m) CTL6(m) LE(m(7)),
271 #define CTL8(m) CTL7(m) LE(m(8)),
272 #define CTL9(m) CTL8(m) LE(m(9)),
273 #define CTL10(m) CTL9(m) LE(m(10)),
274 #define CTL11(m) CTL10(m) LE(m(11)),
275 #define CTL12(m) CTL11(m) LE(m(12)),
276 #define CTL13(m) CTL12(m) LE(m(13)),
277 #define CTL14(m) CTL13(m) LE(m(14)),
278 #define CTL15(m) CTL14(m) LE(m(15)),
279 #define CTL16(m) CTL15(m) LE(m(16)),
280 #define CTL17(m) CTL16(m) LE(m(17)),
281 #define CTL18(m) CTL17(m) LE(m(18)),
282 #define CTL19(m) CTL18(m) LE(m(19)),
283 
284 // ---------------------------------------------------------------------------
285 // Stringification Macros
286 // ---------------------------------------------------------------------------
287 
288 // macro to stringify arguments, which are not expanded, e.g.
289 // #define A B
290 // STRING_NE(A) --> "A"
291 #define STRING_NE(x) #x
292 
293 // 2nd level macro to stringify arguments, which are expanded, e.g.
294 // #define A B
295 // STRING(A) --> "B"
296 #define STRING(m) STRING_NE(m)
297 
298 // Issues with generating stringified lists:
299 //
300 // The argument to STRING cannot contain commas, e.g.
301 // #define CSL a1, a2
302 // STRING(CSL) --> error: macro "STRING" passed 2 arguments...
303 //
304 // Grouping the arguments with (), makes them part of the string, e.g.
305 // #define STRINGP(x) STRING( (x) )
306 // STRINGP(CSL) --> "(a1, a2)"
307 //
308 // Workaround: stringify the elements individually, which are then
309 // concatenated into one string by the compiler, e.g., generate
310 // "a1" ", " "a2"
311 
312 // macro generating a comma-separated, stringified list
313 //
314 // usage: pass the name of a macro taking a number argument, e.g.
315 // #define MY_MACRO(n) a##n
316 // SCSL0(MY_MACRO) -->
317 // SCSL1(MY_MACRO) --> "a1"
318 // SCSL2(MY_MACRO) --> "a1" ", " "a2"
319 // ...
320 #define SCSL0(m)
321 #define SCSL1(m) STRING(m(1))
322 #define SCSL2(m) SCSL1(m) ", " STRING(m(2))
323 #define SCSL3(m) SCSL2(m) ", " STRING(m(3))
324 #define SCSL4(m) SCSL3(m) ", " STRING(m(4))
325 #define SCSL5(m) SCSL4(m) ", " STRING(m(5))
326 #define SCSL6(m) SCSL5(m) ", " STRING(m(6))
327 #define SCSL7(m) SCSL6(m) ", " STRING(m(7))
328 #define SCSL8(m) SCSL7(m) ", " STRING(m(8))
329 #define SCSL9(m) SCSL8(m) ", " STRING(m(9))
330 #define SCSL10(m) SCSL9(m) ", " STRING(m(10))
331 #define SCSL11(m) SCSL10(m) ", " STRING(m(11))
332 #define SCSL12(m) SCSL11(m) ", " STRING(m(12))
333 #define SCSL13(m) SCSL12(m) ", " STRING(m(13))
334 #define SCSL14(m) SCSL13(m) ", " STRING(m(14))
335 #define SCSL15(m) SCSL14(m) ", " STRING(m(15))
336 #define SCSL16(m) SCSL15(m) ", " STRING(m(16))
337 #define SCSL17(m) SCSL16(m) ", " STRING(m(17))
338 #define SCSL18(m) SCSL17(m) ", " STRING(m(18))
339 #define SCSL19(m) SCSL18(m) ", " STRING(m(19))
340 
341 // macro generating a comma-preceded, stringified list
342 //
343 // usage: pass the name of a macro taking a number argument, e.g.
344 // #define MY_MACRO(n) a##n
345 // SCPL0(MY_MACRO) -->
346 // SCPL1(MY_MACRO) --> ", " "a1"
347 // SCPL2(MY_MACRO) --> ", " "a1" ", " "a2"
348 // ...
349 #define SCPL0(m)
350 #define SCPL1(m) ", " STRING(m(1))
351 #define SCPL2(m) SCPL1(m) ", " STRING(m(2))
352 #define SCPL3(m) SCPL2(m) ", " STRING(m(3))
353 #define SCPL4(m) SCPL3(m) ", " STRING(m(4))
354 #define SCPL5(m) SCPL4(m) ", " STRING(m(5))
355 #define SCPL6(m) SCPL5(m) ", " STRING(m(6))
356 #define SCPL7(m) SCPL6(m) ", " STRING(m(7))
357 #define SCPL8(m) SCPL7(m) ", " STRING(m(8))
358 #define SCPL9(m) SCPL8(m) ", " STRING(m(9))
359 #define SCPL10(m) SCPL9(m) ", " STRING(m(10))
360 #define SCPL11(m) SCPL10(m) ", " STRING(m(11))
361 #define SCPL12(m) SCPL11(m) ", " STRING(m(12))
362 #define SCPL13(m) SCPL12(m) ", " STRING(m(13))
363 #define SCPL14(m) SCPL13(m) ", " STRING(m(14))
364 #define SCPL15(m) SCPL14(m) ", " STRING(m(15))
365 #define SCPL16(m) SCPL15(m) ", " STRING(m(16))
366 #define SCPL17(m) SCPL16(m) ", " STRING(m(17))
367 #define SCPL18(m) SCPL17(m) ", " STRING(m(18))
368 #define SCPL19(m) SCPL18(m) ", " STRING(m(19))
369 
370 // ---------------------------------------------------------------------------
371 // Name Definitions used in Wrapper Function Templates
372 // ---------------------------------------------------------------------------
373 
374 // JNI environment parameter declaration
375 #define JEPD JNIEnv * env
376 
377 // Stringified JNI environment type
378 #define SJET "JNIEnv *"
379 
380 // ---------------------------------------------------------------------------
381 
382 // JNI Java class parameter declaration
383 #define JCPD jclass cls
384 
385 // Stringified JNI Java class type
386 #define SJCT "jclass"
387 
388 // ---------------------------------------------------------------------------
389 
390 // Template formal result type declaration
391 #define TFRTD typename RT
392 
393 // C formal result type
394 #define CFRT typename RT::CF_t
395 
396 // Java formal result type
397 #define JFRT typename RT::JF_t
398 
399 // Java actual result type
400 #define JART typename RT::JA_t
401 
402 // C actual result type
403 #define CART typename RT::CA_t
404 
405 // Stringified Java formal result type
406 #define SJFRT "RT::JF_t"
407 
408 // C actual result declaration
409 #define CARD CART car
410 
411 // Java actual result declaration
412 #define JARD JART jar = 0
413 
414 // ---------------------------------------------------------------------------
415 
416 // Template formal object type declaration
417 #define TFOT typename OT
418 
419 // Short C formal object type (not preceded by 'typename')
420 #define SCFOT OT::CF_t
421 
422 // Java actual object type
423 #define JAOT typename OT::JA_t
424 
425 // C actual object type
426 #define CAOT typename OT::CA_t
427 
428 // Java formal object parameter declaration
429 #define JFOPD typename OT::JF_t jfo
430 
431 // Stringified Java formal object type
432 #define SJFOT "OT::JF_t"
433 
434 // ---------------------------------------------------------------------------
435 
436 // Template formal parameter type
437 #define TFPT(n) P##n##T
438 
439 // Template formal parameter type declaration
440 #define TFPTD(n) typename P##n##T
441 
442 // C formal parameter type
443 #define CFPT(n) typename P##n##T::CF_t
444 
445 // Java formal parameter type
446 #define JFPT(n) typename P##n##T::JF_t
447 
448 // Java actual parameter type
449 #define JAPT(n) typename P##n##T::JA_t
450 
451 // C actual parameter type
452 #define CAPT(n) typename P##n##T::CA_t
453 
454 // Java formal parameter declaration
455 #define JFPD(n) JFPT(n) jfp##n
456 
457 // Java formal parameter
458 #define JFP(n) jfp##n
459 
460 // C actual parameter
461 #define CAP(n) cap##n
462 
463 // Short Java formal parameter type
464 #define SJFPT(n) P##n##T::JF_t
465 
466 // ---------------------------------------------------------------------------
467 
468 // status flag declaration
469 #define SFD int s = 1; (void)s;
470 
471 #define PARAM_CONV_BEGIN(n) \
472  JAPT(n) jap##n = cast< JAPT(n), JFPT(n) >(jfp##n); \
473  CAPT(n) cap##n = Param< JAPT(n), CAPT(n) >::convert(s, jap##n, env); \
474  if (s == 0) {
475 
476 #define PARAM_CONV_END(n) \
477  Param< JAPT(n), CAPT(n) >::release(cap##n, jap##n, env); \
478  }
479 
480 #define TARGET_CONV_BEGIN \
481  JAOT jao = cast< JAOT, TFOT::JF_t >(jfo); \
482  CAOT & cao = Target< JAOT, CAOT >::convert(s, jao, env); \
483  if (s == 0) {
484 
485 #define TARGET_CONV_END \
486  Target< JAOT, CAOT >::release(cao, jao, env); \
487  }
488 
489 #define RESULT_CONV \
490  jar = Result< JART, CART >::convert(car, env);
491 
492 #define RESULT_CAST \
493  cast< JFRT, JART >(jar);
494 
495 // ---------------------------------------------------------------------------
496 // Data Member Access
497 // ---------------------------------------------------------------------------
498 
499 // non-member field or static field read access
500 template< TFRTD,
501  CFRT & D >
502 inline
503 JFRT
504 gget(JEPD, JCPD)
505 {
506  TRACE(SJFRT " gget(" SJET ", " SJCT ")");
507  (void)cls;
508  JARD;
509  CARD = D;
510  RESULT_CONV;
511  return RESULT_CAST;
512 }
513 
514 // member field read access
515 template< TFOT,
516  TFRTD,
517  CFRT SCFOT::*D >
518 inline JFRT
519 gget(JEPD, JFOPD)
520 {
521  TRACE(SJFRT " gget(" SJET ", " SJFOT ")");
522  JARD;
523  SFD;
524  TARGET_CONV_BEGIN;
525  CARD = (cao).*D;
526  RESULT_CONV;
527  TARGET_CONV_END;
528  return RESULT_CAST;
529 }
530 
531 // non-member field or static field write access
532 template< TFPTD(1),
533  CFPT(1) & D >
534 inline
535 void
536 gset(JEPD, JCPD, JFPD(1))
537 {
538  TRACE("void" " gset(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
539  (void)cls;
540  SFD;
541  PARAM_CONV_BEGIN(1);
542  D = CAP(1);
543  PARAM_CONV_END(1);
544 }
545 
546 // member field write access
547 template< TFOT,
548  TFPTD(1),
549  CFPT(1) SCFOT::*D >
550 inline void
551 gset(JEPD, JFOPD CPL1(JFPD))
552 {
553  TRACE("void" " gset(" SJET ", " SJFOT ", " STRING(SJFPT(1)) ")");
554  SFD;
555  TARGET_CONV_BEGIN;
556  PARAM_CONV_BEGIN(1);
557  (cao).*D = CAP(1);
558  PARAM_CONV_END(1);
559  TARGET_CONV_END;
560 }
561 
562 // ---------------------------------------------------------------------------
563 // Non-Member and Static Member Function Calls, No-Return
564 // ---------------------------------------------------------------------------
565 
566 // parameters: n = n-ary function
567 #define TFD_F(n) \
568  template< CTL##n(TFPTD) \
569  void F(CSL##n(CFPT)) > \
570  inline void \
571  gcall_fv(JEPD, JCPD CPL##n(JFPD)) \
572  { \
573  TRACE("void" " gcall_fv(" SJET ", " SJCT SCPL##n(SJFPT) ")"); \
574  (void)env; (void)cls; \
575  SFD; \
576  BSL##n(PARAM_CONV_BEGIN); \
577  F( CSL##n(CAP) ); \
578  RBSL##n(PARAM_CONV_END); \
579  }
580 
581 // generate the function templates (separate lines for proper error messages)
582 TFD_F(0)
583 TFD_F(1)
584 TFD_F(2)
585 TFD_F(3)
586 TFD_F(4)
587 TFD_F(5)
588 TFD_F(6)
589 TFD_F(7)
590 TFD_F(8)
591 TFD_F(9)
592 TFD_F(10)
593 TFD_F(11)
594 TFD_F(12)
595 TFD_F(13)
596 TFD_F(14)
597 TFD_F(15)
598 TFD_F(16)
599 TFD_F(17)
600 TFD_F(18)
601 TFD_F(19)
602 
603 // ---------------------------------------------------------------------------
604 // Non-Member and Static Member Function Calls, Return
605 // ---------------------------------------------------------------------------
606 
607 // parameters: n = n-ary function
608 #define TFD_FR(n) \
609  template< TFRTD, \
610  CTL##n(TFPTD) \
611  CFRT F(CSL##n(CFPT)) > \
612  inline JFRT \
613  gcall_fr(JEPD, JCPD CPL##n(JFPD)) \
614  { \
615  TRACE(SJFRT " gcall_fr(" SJET ", " SJCT SCPL##n(SJFPT) ")"); \
616  (void)cls; \
617  JARD; \
618  SFD; \
619  BSL##n(PARAM_CONV_BEGIN); \
620  CARD = F( CSL##n(CAP) ); \
621  RESULT_CONV; \
622  RBSL##n(PARAM_CONV_END); \
623  return RESULT_CAST; \
624  }
625 
626 // generate the function templates (separate lines help error messages)
627 TFD_FR(0)
628 TFD_FR(1)
629 TFD_FR(2)
630 TFD_FR(3)
631 TFD_FR(4)
632 TFD_FR(5)
633 TFD_FR(6)
634 TFD_FR(7)
635 TFD_FR(8)
636 TFD_FR(9)
637 TFD_FR(10)
638 TFD_FR(11)
639 TFD_FR(12)
640 TFD_FR(13)
641 TFD_FR(14)
642 TFD_FR(15)
643 TFD_FR(16)
644 TFD_FR(17)
645 TFD_FR(18)
646 TFD_FR(19)
647 
648 // ---------------------------------------------------------------------------
649 // Non-Static Const/Non-Const Member Function Calls, No-Return
650 // ---------------------------------------------------------------------------
651 
652 // parameters: n = n-ary function
653 //
654 // we do not generate a separate set of templates for const members anymore:
655 // cm = empty or 'const'
656 // #define TFD_MF(n,cm)
657 // ... void (SCFOT::*F)(CSL##n(CFPT)) cm >
658 // for
659 // - leads to template ambiguities with const member function ptr type
660 // - empty macro arguments are undefined in ISO C90 and ISO C++98
661 //
662 #define TFD_MF(n) \
663  template< TFOT, \
664  CTL##n(TFPTD) \
665  void (SCFOT::*F)(CSL##n(CFPT)) > \
666  inline void \
667  gcall_mfv(JEPD, JFOPD CPL##n(JFPD)) \
668  { \
669  TRACE("void" " gcall_mfv(" SJET ", " SJFOT SCPL##n(SJFPT) ")"); \
670  SFD; \
671  TARGET_CONV_BEGIN; \
672  BSL##n(PARAM_CONV_BEGIN); \
673  ((cao).*F)( CSL##n(CAP) ); \
674  RBSL##n(PARAM_CONV_END); \
675  TARGET_CONV_END; \
676  }
677 
678 // generate the function templates (separate lines help error messages)
679 TFD_MF(0)
680 TFD_MF(1)
681 TFD_MF(2)
682 TFD_MF(3)
683 TFD_MF(4)
684 TFD_MF(5)
685 TFD_MF(6)
686 TFD_MF(7)
687 TFD_MF(8)
688 TFD_MF(9)
689 TFD_MF(10)
690 TFD_MF(11)
691 TFD_MF(12)
692 TFD_MF(13)
693 TFD_MF(14)
694 TFD_MF(15)
695 TFD_MF(16)
696 TFD_MF(17)
697 TFD_MF(18)
698 TFD_MF(19)
699 
700 // ---------------------------------------------------------------------------
701 // Non-Static Const/Non-Const Member Function Calls, Return
702 // ---------------------------------------------------------------------------
703 
704 // parameters: n = n-ary, cm = const member function qualifier
705 //
706 // we do not generate a separate set of templates for const members anymore:
707 // cm = empty or 'const'
708 // #define TFD_MFR(n,cm)
709 // ... CFRT (SCFOT::*F)(CSL##n(CFPT)) cm >
710 // for
711 // - leads to template ambiguities with const member function ptr type
712 // - empty macro arguments are undefined in ISO C90 and ISO C++98
713 //
714 #define TFD_MFR(n) \
715  template< TFOT, \
716  TFRTD, \
717  CTL##n(TFPTD) \
718  CFRT (SCFOT::*F)(CSL##n(CFPT)) > \
719  inline JFRT \
720  gcall_mfr(JEPD, JFOPD CPL##n(JFPD)) \
721  { \
722  TRACE(SJFRT " gcall_mfr(" SJET ", " SJFOT SCPL##n(SJFPT) ")"); \
723  JARD; \
724  SFD; \
725  TARGET_CONV_BEGIN; \
726  BSL##n(PARAM_CONV_BEGIN); \
727  CARD = ((cao).*F)( CSL##n(CAP) ); \
728  RESULT_CONV; \
729  RBSL##n(PARAM_CONV_END); \
730  TARGET_CONV_END; \
731  return RESULT_CAST; \
732  }
733 
734 // generate the function templates (separate lines help error messages)
735 TFD_MFR(0)
736 TFD_MFR(1)
737 TFD_MFR(2)
738 TFD_MFR(3)
739 TFD_MFR(4)
740 TFD_MFR(5)
741 TFD_MFR(6)
742 TFD_MFR(7)
743 TFD_MFR(8)
744 TFD_MFR(9)
745 TFD_MFR(10)
746 TFD_MFR(11)
747 TFD_MFR(12)
748 TFD_MFR(13)
749 TFD_MFR(14)
750 TFD_MFR(15)
751 TFD_MFR(16)
752 TFD_MFR(17)
753 TFD_MFR(18)
754 TFD_MFR(19)
755 
756 // ---------------------------------------------------------------------------
757 // Internal C++ Constructor/Destructor/Index Access Wrappers
758 // ---------------------------------------------------------------------------
759 
760 // parameters: n = n-ary
761 
762 // class template calling the array destructor
763 template< typename C > struct ArrayHelper;
764 
765 template< typename C >
766 struct ArrayHelper< C * > {
767  static void
768  cdelete(C * p0) {
769  TRACE("void ArrayHelper::cdelete(C *)");
770  delete[] p0;
771  }
772 
773  static C *
774  ccreate(int32_t p0) {
775  TRACE("C * ArrayHelper::ccreate(int32_t)");
776  // ISO C++: 'new' throws std::bad_alloc if unsuccessful
777  return new C[p0];
778  }
779 
780  static C *
781  cat(C * p0, int32_t i) {
782  TRACE("C * ArrayHelper::cat(C *)");
783  return (p0 + i);
784  }
785 };
786 
787 template< typename C >
789  static void
790  cdelete(C & p0) {
791  TRACE("void ArrayHelper::cdelete(C &)");
792  ArrayHelper< C * >::cdelete(&p0);
793  }
794 
795  static C &
796  ccreate(int32_t p0) {
797  TRACE("C & ArrayHelper::ccreate(int32_t)");
798  return *ArrayHelper< C * >::ccreate(p0);
799  }
800 
801  static C &
802  cat(C & p0, int32_t i) {
803  TRACE("C & ArrayHelper::cat(C &)");
804  return *ArrayHelper< C * >::cat(&p0, i);
805  }
806 };
807 
808 // ---------------------------------------------------------------------------
809 
810 // class template calling the destructor
811 template< typename C > struct Destructor;
812 
813 template< typename C >
815  static void
816  cdelete(C * p0) {
817  TRACE("void Destructor::cdelete(C *)");
818  delete p0;
819  }
820 };
821 
822 template< typename C >
824  static void
825  cdelete(C & p0) {
826  TRACE("void Destructor::cdelete(C &)");
827  Destructor< C * >::cdelete(&p0);
828  }
829 };
830 
831 // Template formal parameter type (redefine)
832 #define CC_TFPT(n) P##n##_CF_t
833 
834 // Template formal parameter type declaration (redefine)
835 #define CC_TFPTD(n) typename CC_TFPT(n)
836 
837 // C formal parameter type (redefine)
838 #define CC_CFPT(n) CC_TFPT(n)
839 
840 // C formal parameter
841 #define CC_CFP(n) cfp##n
842 
843 // C formal parameter declaration
844 #define CC_CFPD(n) CC_CFPT(n) CC_CFP(n)
845 
846 // n-ary class templates calling constructors
847 #define TFD_CC(n) \
848  template< typename C CPL##n(CC_TFPTD) > struct Constructor##n; \
849  \
850  template< typename C CPL##n(CC_TFPTD) > \
851  struct Constructor##n< C * CPL##n(CC_TFPT) > { \
852  static C * \
853  ccreate(CSL##n(CC_CFPD)) { \
854  TRACE("C * ccreate(" SCSL##n(CC_TFPT) ")"); \
855  return new C(CSL##n(CC_CFP)); \
856  } \
857  }; \
858  \
859  template< typename C CPL##n(CC_TFPTD) > \
860  struct Constructor##n< C & CPL##n(CC_TFPT) > { \
861  static C & \
862  ccreate(CSL##n(CC_CFPD)) { \
863  TRACE("C & ccreate(" SCSL##n(CC_TFPT) ")"); \
864  return *Constructor##n< C * CPL##n(CC_TFPT) > \
865  ::ccreate(CSL##n(CC_CFP)); \
866  } \
867  };
868 
869 // generate the class templates (separate lines help error messages)
870 TFD_CC(0)
871 TFD_CC(1)
872 TFD_CC(2)
873 TFD_CC(3)
874 TFD_CC(4)
875 TFD_CC(5)
876 TFD_CC(6)
877 TFD_CC(7)
878 TFD_CC(8)
879 TFD_CC(9)
880 TFD_CC(10)
881 TFD_CC(11)
882 TFD_CC(12)
883 TFD_CC(13)
884 TFD_CC(14)
885 TFD_CC(15)
886 TFD_CC(16)
887 TFD_CC(17)
888 TFD_CC(18)
889 TFD_CC(19)
890 
891 // ---------------------------------------------------------------------------
892 // Constructor, Destructor, and Index Access Calls
893 // ---------------------------------------------------------------------------
894 
895 // array delete template function definition
896 template< TFPTD(1) >
897 inline
898 void
899 gdeleteArray(JEPD, JCPD, JFPD(1))
900 {
901  TRACE("void gdeleteArray(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
902  (void)cls;
903  // not using gcall_fv<...>(...) due to call to detachWrapper()
904  SFD;
905  PARAM_CONV_BEGIN(1);
906 #ifdef JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
907  detachWrapper(jap1, env);
908 #endif // JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
909  ArrayHelper< CFPT(1) >::cdelete(CAP(1));
910  PARAM_CONV_END(1);
911 }
912 
913 // array create template function definition
914 template< TFRTD, TFPTD(1) >
915 inline
916 JFRT
917 gcreateArray(JEPD, JCPD, JFPD(1))
918 {
919  TRACE(SJFRT " gcreateArray(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
920  return gcall_fr< RT, TFPT(1),
921  &ArrayHelper< CFRT >::ccreate
922  >(env, cls, JFP(1));
923 }
924 
925 // array index access template function definition
926 template< TFRTD, TFPTD(1), TFPTD(2) >
927 inline
928 JFRT
929 gat(JEPD, JCPD, JFPD(1), JFPD(2))
930 {
931  TRACE(SJFRT " gat(" SJET ", " SJCT ", " STRING(SJFPT(1)) ", " STRING(SJFPT(2)) ")");
932  return gcall_fr< RT, TFPT(1), TFPT(2),
933  &ArrayHelper< CFRT >::cat
934  >(env, cls, JFP(1), JFP(2));
935 }
936 
937 // ---------------------------------------------------------------------------
938 
939 // destructor template function definition
940 template< TFPTD(1) >
941 inline
942 void
943 gdelete(JEPD, JCPD, JFPD(1))
944 {
945  TRACE("void gdelete(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
946  (void)cls;
947  // not using gcall_fv<...>(...) due to call to detachWrapper()
948  SFD;
949  PARAM_CONV_BEGIN(1);
950 #ifdef JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
951  detachWrapper(jap1, env);
952 #endif // JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
953  Destructor< CFPT(1) >::cdelete(CAP(1));
954  PARAM_CONV_END(1);
955 }
956 
957 // n-ary constructor template function definition
958 #define TFD_C(n) \
959  template< TFRTD CPL##n(TFPTD) > \
960  inline JFRT \
961  gcreate(JEPD, JCPD CPL##n(JFPD)) \
962  { \
963  TRACE(SJFRT " gcreate(" SJET ", " SJCT SCSL##n(SJFPT) ")"); \
964  return gcall_fr< RT, CTL##n(TFPT) \
965  &Constructor##n< CFRT CPL##n(CFPT) >::ccreate \
966  >(env, cls CPL##n(JFP)); \
967  }
968 
969 // generate the function templates (separate lines help error messages)
970 TFD_C(0)
971 TFD_C(1)
972 TFD_C(2)
973 TFD_C(3)
974 TFD_C(4)
975 TFD_C(5)
976 TFD_C(6)
977 TFD_C(7)
978 TFD_C(8)
979 TFD_C(9)
980 TFD_C(10)
981 TFD_C(11)
982 TFD_C(12)
983 TFD_C(13)
984 TFD_C(14)
985 TFD_C(15)
986 TFD_C(16)
987 TFD_C(17)
988 TFD_C(18)
989 TFD_C(19)
990 
991 // ---------------------------------------------------------------------------
992 
993 #endif // jtie_gcalls_hpp