Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / tests / Any / Recursive / client.cpp
blobe030acbe37695c5abdd025fb03fecca96c25bc04
1 #include "TestC.h"
2 #include "tao/IFR_Client/IFR_BaseC.h"
3 #include "tao/TypeCodeFactory/TypeCodeFactory_Loader.h"
5 #include "ace/Get_Opt.h"
7 #include <algorithm>
8 #include <functional>
10 const ACE_TCHAR *ior = ACE_TEXT("file://test.ior");
12 int
13 parse_args (int argc, ACE_TCHAR *argv[])
15 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:"));
16 int c;
18 while ((c = get_opts ()) != -1)
19 switch (c)
21 case 'k':
22 ior = get_opts.opt_arg ();
23 break;
25 case '?':
26 case 'h':
27 default:
28 ACE_ERROR_RETURN ((LM_ERROR,
29 "usage: %s "
30 "-k <ior> "
31 "\n",
32 argv [0]),
33 -1);
36 // Successful command line parsing.
37 return 0;
40 template<typename T> void dump (T *); // Forward declaration.
42 template<>
43 void
44 dump<Test::RecursiveStruct> (Test::RecursiveStruct * data)
46 ACE_DEBUG ((LM_DEBUG,
47 "Test::RecursiveStruct\n"
48 "%d\n"
49 "%u\n"
50 "%d\n"
51 "%d\n",
52 data->i,
53 data->recursive_structs.length (),
54 data->recursive_structs[0].i,
55 data->recursive_structs[1].i));
58 template<>
59 void
60 dump<Test::NestedRecursiveStruct> (Test::NestedRecursiveStruct * data)
62 ACE_DEBUG ((LM_DEBUG,
63 "Test::NestedRecursiveStruct\n"
64 "%d\n"
65 "%u\n"
66 "%d\n"
67 "%d\n",
68 data->i,
69 data->ins.recursive_structs.length (),
70 data->ins.recursive_structs[0].i,
71 data->ins.recursive_structs[1].i));
74 template<>
75 void
76 dump<Test::RecursiveUnion> (Test::RecursiveUnion * data)
78 ACE_DEBUG ((LM_DEBUG, "Test::RecursiveUnion\n"));
80 switch (data->_d ())
82 case 0:
84 Test::RecursiveUnionSeq const & seq = data->recursive_unions ();
86 ACE_DEBUG ((LM_DEBUG,
87 "%u\n"
88 "%d\n"
89 "%u\n",
90 seq.length (),
91 seq[0].i (),
92 seq[1].recursive_unions ().length ()));
94 break;
95 default:
96 ACE_DEBUG ((LM_DEBUG,
97 "%d\n",
98 data->i ()));
99 break;
103 template<typename T>
104 void
105 perform_invocation (Test::Hello_ptr hello,
106 CORBA::Any const & the_any)
108 // Execute more than once to help verify that mutable recursive
109 // TypeCode state is managed correctly.
110 for (unsigned int n = 0; n < 2; ++n)
112 CORBA::Any_var my_any =
113 hello->get_any (the_any);
115 const T * my_foo = 0;
116 if (!(my_any.in () >>= my_foo))
117 throw Test::Demarshaling_From_Any_Failed ();
119 // ACE_DEBUG ((LM_DEBUG, "Data dump:\n"));
120 // dump<T> (my_foo);
122 CORBA::TypeCode_var the_tc = the_any.type ();
123 CORBA::TypeCode_var my_tc = my_any->type ();
125 CORBA::Boolean const equal_tc =
126 the_tc->equal (my_tc.in ());
128 if (!equal_tc)
129 throw Test::Recursive_Type_In_Any_Test_Failed ();
131 CORBA::Boolean const equiv_tc =
132 the_tc->equivalent (my_tc.in ());
134 if (!equiv_tc)
135 throw Test::Recursive_Type_In_Any_Test_Failed ();
139 void
140 recursive_struct_test (CORBA::ORB_ptr /* orb */,
141 Test::Hello_ptr hello)
143 ACE_DEBUG ((LM_INFO,
144 "Executing recursive struct test\n"));
146 Test::RecursiveStruct foo;
148 foo.recursive_structs.length (2);
149 foo.recursive_structs[0].i = 37;
150 foo.recursive_structs[1].i = 11034;
151 foo.i = 12;
153 CORBA::Any the_any;
154 the_any <<= foo;
156 ::perform_invocation<Test::RecursiveStruct> (hello,
157 the_any);
160 void
161 nested_recursive_struct_test (CORBA::ORB_ptr /* orb */,
162 Test::Hello_ptr hello)
164 ACE_DEBUG ((LM_INFO,
165 "Executing nested recursive struct test\n"));
167 Test::NestedRecursiveStruct foo;
169 foo.ins.recursive_structs.length (2);
170 foo.ins.recursive_structs[0].i = 37;
171 foo.ins.recursive_structs[1].i = 11034;
172 foo.i = 12;
174 CORBA::Any the_any;
175 the_any <<= foo;
177 ::perform_invocation<Test::NestedRecursiveStruct> (hello, the_any);
181 void
182 recursive_union_test (CORBA::ORB_ptr /* orb */,
183 Test::Hello_ptr hello)
185 ACE_DEBUG ((LM_INFO,
186 "Executing recursive union test\n"));
188 CORBA::Any the_any;
190 Test::EnumUnion foo_enum;
191 static CORBA::Short const test_long = 23901;
193 // First simple case, just an union with an enum as discriminator
194 foo_enum.i (test_long);
195 the_any <<= foo_enum;
197 ::perform_invocation<Test::EnumUnion> (hello, the_any);
199 // Non-recursive member case.
200 Test::RecursiveUnion foo;
201 foo.i (test_long);
203 the_any <<= foo;
205 ::perform_invocation<Test::RecursiveUnion> (hello, the_any);
207 Test::RecursiveUnion2 foo2;
208 foo2.i (test_long);
210 the_any <<= foo2;
212 ::perform_invocation<Test::RecursiveUnion2> (hello,
213 the_any);
215 Test::RecursiveUnion3 foo3;
216 foo3.a (test_long);
218 the_any <<= foo3;
220 int n;
221 for (n=0; n < 200; ++n)
223 ::perform_invocation<Test::RecursiveUnion3> (hello,
224 the_any);
228 // Recursive member case.
229 Test::RecursiveUnionSeq seq;
230 seq.length (2);
231 seq[0].i (37);
232 seq[1].recursive_unions (Test::RecursiveUnionSeq ());
234 foo.recursive_unions (seq);
236 the_any <<= foo;
238 ::perform_invocation<Test::RecursiveUnion> (hello,
239 the_any);
241 // Recursive member case with no default member
242 Test::RecursiveUnionSeqNoDefault seqnodefault;
243 seqnodefault.length (2);
244 seqnodefault[0].a (37);
245 seqnodefault[1].recursive_unions (Test::RecursiveUnionSeqNoDefault ());
247 Test::RecursiveUnionNoDefault foonodefault;
248 foonodefault.recursive_unions (seqnodefault);
250 the_any <<= foonodefault;
252 ::perform_invocation<Test::RecursiveUnionNoDefault> (hello,
253 the_any);
255 // Recursive member case with enum .
256 Test::VSortRecursiveUnionSeq vsortseq;
257 vsortseq.length (2);
258 vsortseq[0].i (37);
259 vsortseq[1].recursive_unions (Test::VSortRecursiveUnionSeq ());
261 Test::VSortRecursiveUnion vsort_foo;
262 vsort_foo.recursive_unions (vsortseq);
264 the_any <<= vsort_foo;
266 ::perform_invocation<Test::VSortRecursiveUnion> (hello,
267 the_any);
269 // Non-recursive member case with enum .
270 Test::NonRecursiveUnionWithEnum val;
271 the_any <<= val;
273 ::perform_invocation<Test::NonRecursiveUnionWithEnum> (hello,
274 the_any);
276 // Non-recursive member case with recursive struct .
278 Test::NonRecursiveUnionWithStringStruct val2;
279 the_any <<= val2;
281 ::perform_invocation<Test::NonRecursiveUnionWithStringStruct> (hello, the_any);
285 void
286 indirectly_recursive_valuetype_test (CORBA::ORB_ptr /* orb */,
287 Test::Hello_ptr /* hello */)
289 ACE_DEBUG ((LM_INFO,
290 "Executing indirectly recursive valuetype test\n"));
292 ACE_DEBUG ((LM_WARNING,
293 " Currently unimplemented.\n"));
296 void
297 directly_recursive_valuetype_test (CORBA::ORB_ptr /* orb */,
298 Test::Hello_ptr /* hello */)
300 ACE_DEBUG ((LM_INFO,
301 "Executing directly recursive valuetype test\n"));
303 ACE_DEBUG ((LM_WARNING,
304 " Currently unimplemented.\n"));
307 #if TAO_HAS_MINIMUM_CORBA == 0
309 void
310 recursive_struct_typecodefactory_test (CORBA::ORB_ptr orb,
311 Test::Hello_ptr hello)
313 ACE_DEBUG ((LM_INFO,
314 "Executing recursive struct via TypeCodeFactory test\n"));
316 Test::RecursiveStruct foo;
318 foo.recursive_structs.length (2);
319 foo.recursive_structs[0].i = 37;
320 foo.recursive_structs[1].i = 11034;
321 foo.i = 12;
323 CORBA::Any the_any;
324 the_any <<= foo;
326 CORBA::TypeCode_var recursive_tc =
327 orb->create_recursive_tc ("IDL:Test/RecursiveStruct:1.0");
329 CORBA::TypeCode_var seq_tc =
330 orb->create_sequence_tc (0,
331 recursive_tc.in ());
333 CORBA::StructMemberSeq members (3);
334 members.length (3);
335 members[0].name = "recursive_structs";
336 members[0].type = seq_tc;
337 members[1].name = "i";
338 members[1].type = CORBA::TypeCode::_duplicate (CORBA::_tc_long);
339 members[2].name = "recursive_structs_second";
340 members[2].type = seq_tc;
342 CORBA::TypeCode_var struct_tc =
343 orb->create_struct_tc ("IDL:Test/RecursiveStruct:1.0",
344 "RecursiveStruct",
345 members);
347 // Reset the underlying TypeCode to the one we just created with the
348 // TypeCodeFactory.
349 the_any.type (struct_tc.in ());
351 ::perform_invocation<Test::RecursiveStruct> (hello,
352 the_any);
355 void
356 recursive_union_typecodefactory_test (CORBA::ORB_ptr /* orb */,
357 Test::Hello_ptr /* hello */)
359 ACE_DEBUG ((LM_INFO,
360 "Executing recursive union via TypeCodeFactory test\n"));
362 ACE_DEBUG ((LM_WARNING,
363 " Currently unimplemented.\n"));
366 void
367 indirectly_recursive_valuetype_typecodefactory_test (
368 CORBA::ORB_ptr /* orb */,
369 Test::Hello_ptr /* hello */)
371 ACE_DEBUG ((LM_INFO,
372 "Executing indirectly recursive valuetype via "
373 "TypeCodeFactory test\n"));
375 ACE_DEBUG ((LM_WARNING,
376 " Currently unimplemented.\n"));
379 void
380 directly_recursive_valuetype_typecodefactory_test (CORBA::ORB_ptr /* orb */,
381 Test::Hello_ptr /* hello */)
383 ACE_DEBUG ((LM_INFO,
384 "Executing directly recursive valuetype via "
385 "TypeCodeFactory test\n"));
387 ACE_DEBUG ((LM_WARNING,
388 " Currently unimplemented.\n"));
391 #endif /* TAO_HAS_MINIMUM_CORBA == 0 */
395 * @struct Caller
397 * @brief Test method invocation functor.
399 * Test method invocation functor.
401 template <typename T>
402 struct Caller : public std::function<void(T)>
404 /// Constructor.
405 Caller (CORBA::ORB_ptr o, Test::Hello_ptr h)
406 : orb (CORBA::ORB::_duplicate (o))
407 , hello (Test::Hello::_duplicate (h))
408 , success (true)
412 /// Function call operator overload.
413 void operator() (T f)
417 f (orb.in (),
418 hello.in ());
420 catch (const CORBA::Exception& ex)
422 ex._tao_print_exception ("Exception thrown:");
424 success = false;
428 CORBA::ORB_var orb;
429 Test::Hello_var hello;
430 bool success;
434 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
438 CORBA::ORB_var orb =
439 CORBA::ORB_init (argc, argv);
441 if (parse_args (argc, argv) != 0)
442 return 1;
444 CORBA::Object_var tmp =
445 orb->string_to_object(ior);
447 Test::Hello_var hello =
448 Test::Hello::_narrow(tmp.in ());
450 if (CORBA::is_nil (hello.in ()))
452 ACE_ERROR_RETURN ((LM_DEBUG,
453 "Nil Test::Hello reference <%s>\n",
454 ior),
458 typedef void (*test_func) (CORBA::ORB_ptr,
459 Test::Hello_ptr);
461 static test_func const tests[] =
463 recursive_struct_test
464 , nested_recursive_struct_test
465 , indirectly_recursive_valuetype_test
466 , directly_recursive_valuetype_test
467 , recursive_union_test
468 #if TAO_HAS_MINIMUM_CORBA == 0
469 , recursive_struct_typecodefactory_test
470 , recursive_union_typecodefactory_test
471 , indirectly_recursive_valuetype_typecodefactory_test
472 , directly_recursive_valuetype_typecodefactory_test
473 #endif /* TAO_HAS_MINIMUM_CORBA == 0 */
476 static size_t const test_count = sizeof (tests) / sizeof (test_func);
478 // Have some fun with the STL. :-)
479 Caller<test_func> c =
480 std::for_each (tests,
481 tests + test_count,
482 Caller<test_func> (orb.in (),
483 hello.in ()));
485 if (!c.success)
486 throw Test::Recursive_Type_In_Any_Test_Failed ();
488 hello->shutdown ();
490 orb->destroy ();
492 catch (const CORBA::Exception& ex)
494 ex._tao_print_exception ("Exception caught:");
495 return 1;
498 return 0;