Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / CDR_Array_Test.cpp
blob9b68d8a099153f9cbc27f61fb8ae5d4e2255ed1e
2 //=============================================================================
3 /**
4 * @file CDR_Array_Test.cpp
6 * Checks ACE_OutputCDR::write_XX_array.
7 * Checks ACE_InputCDR::read_XX_array.
8 * Checks operator<< and operator>> for CDR Streams in
9 * each of the basic CDR types.
10 * Gives a measure of the speed of the ACE CDR streams wrt those
11 * operations.
13 * @author Cristian Ferretti <cristian_ferretti@yahoo.com>
15 //=============================================================================
18 // For measuring time, choose your method:
19 // Define:
21 // * USE_GETRUSAGE for using ACE_OS::getrusage.
22 // Ticks only when process is running.
24 // * USE_CLOCK for using clock(2).
25 // You're on your own, no ACE_OS:: support.
26 // Ticks only when process is running.
28 // * None of the above for using ACE_High_Res_Timer.
29 // Ticks independent of running state of process.
31 // #define USE_CLOCK
32 // #define USE_GETRUSAGE
34 #if defined(USE_CLOCK)
35 #include <time.h>
36 #endif
38 #include "test_config.h"
39 #include "ace/OS_Memory.h"
40 #include "ace/OS_NS_stdlib.h"
41 #include "ace/Get_Opt.h"
42 #include "ace/CDR_Stream.h"
43 #include "ace/High_Res_Timer.h"
44 #include "ace/ACE.h"
46 #if defined(USE_GETRUSAGE) && !defined(ACE_HAS_GETRUSAGE)
47 #error "Can't define USE_GETRUSAGE on this platform."
48 #endif
51 // Default number of elements for check buffer, for each tested CDR type.
52 // Be aware that time will be affected by the buffer fitting/not fitting
53 // in the cache (ie, if default_total*sizeof(T) bytes fit in the cache).
54 // Also, you want that your time measuring method has a resolution
55 // compatible with this buffer size, if not you will end up measuring 0.
56 // You can change this value with -t option.
57 static const int default_total = 32*1024;
59 // Repeat this many times for each tested CDR type.
60 // We then take the average time that took for each type and report that.
61 // You can change this value with -n option.
62 static const int default_niter = 10;
65 // A simple cronometer in seconds, that encapsulates our time
66 // measuring method.
68 class Crono {
69 public:
70 Crono() {}
71 ~Crono() {}
72 void start ()
74 #if defined(USE_CLOCK)
75 start_ = clock ();
76 #elif defined(USE_GETRUSAGE)
77 ACE_OS::getrusage (RUSAGE_SELF, &start_);
78 #else
79 timer.start ();
80 #endif
82 void stop ()
84 #if defined(USE_CLOCK)
85 end_ = clock ();
86 #elif defined(USE_GETRUSAGE)
87 ACE_OS::getrusage (RUSAGE_SELF, &end_);
88 #else
89 timer.stop ();
90 #endif
92 double read_seconds ()
94 #if defined(USE_CLOCK)
95 return (end_ - start_) / (double) CLOCKS_PER_SEC;
96 #elif defined(USE_GETRUSAGE)
97 timeval diff;
98 diff.tv_sec = end_.ru_utime.tv_sec - start_.ru_utime.tv_sec;
99 diff.tv_usec = end_.ru_utime.tv_usec - start_.ru_utime.tv_usec;
100 while (diff.tv_usec < 0)
102 --diff.tv_sec;
103 diff.tv_usec += ACE_ONE_SECOND_IN_USECS;
106 return diff.tv_sec + diff.tv_usec / double(ACE_ONE_SECOND_IN_USECS);
107 #else
108 ACE_Time_Value tv;
109 timer.elapsed_time(tv);
110 return tv.usec () / 1000000.0;
111 #endif
113 private:
114 #if defined(USE_CLOCK)
115 clock_t start_;
116 clock_t end_;
117 #elif defined(USE_GETRUSAGE)
118 ACE_Rusage start_;
119 ACE_Rusage end_;
120 #else
121 ACE_High_Res_Timer timer;
122 #endif
126 // Our test, performed in the constructor.
127 // T is one of the CDR types.
128 // H is a helper class (described later).
130 // All this stuff is in a class and not in template functions
131 // to avoid having to deal with potential template function
132 // instantiations problems.
134 template<class T, class H> class CDR_Test
136 public:
137 CDR_Test (int total, int niter, int use_array);
138 static void do_test (int total, int niter, int use_array,
139 char* srcbuf, char* dstbuf,
140 int src_offset = 0, int dst_offset = 0);
141 ~CDR_Test ();
143 static void ttoh (const T& t, char* s);
144 static T checkval(int i);
146 private:
147 CDR_Test (const CDR_Test<T, H>&);
148 CDR_Test<T, H>& operator= (const CDR_Test<T, H>&);
151 static ACE_UINT32 seal = 0xdeadbeef;
153 void
154 zero (char* p, size_t k)
156 char* end = p + k;
157 while (p < end)
159 *p++ = '\0';
163 inline int
164 mymax (int a, int b)
166 return (a >= b) ? a : b;
169 void
170 memabort ()
172 ACE_ERROR((LM_ERROR,
173 ACE_TEXT ("new failed, aborting\n")));
174 ACE_OS::exit (1);
177 template<class T, class H>
178 CDR_Test<T, H>::CDR_Test (int total, int niter, int use_array)
180 if (total <= 0)
182 return;
185 char* srcbuf;
186 char* dstbuf;
188 const size_t stotal =
189 (total + 10) * H::size () + sizeof(ACE_UINT32) + ACE_CDR::MAX_ALIGNMENT;
191 ACE_NEW(srcbuf, char[stotal]);
192 if (srcbuf == 0)
194 memabort ();
196 zero(srcbuf, stotal);
198 ACE_NEW(dstbuf, char[stotal]);
199 if (dstbuf == 0)
201 memabort ();
203 zero(dstbuf, stotal);
206 if (use_array)
208 // We want to test all the possible loop unrolling deltas.
209 int t;
210 for (t = total - 3; t <= total; t++)
212 int delta;
213 if (sizeof(long) <= H::size ())
215 delta = 1;
217 else
219 delta = (int) (sizeof(long) / H::size ());
222 // We want to test all the posible source/destination buffer
223 // alignment combinations.
224 int sk;
225 for (sk = 0; sk < delta; sk++)
227 int dk;
228 for (dk = 0; dk < delta; dk++)
230 int tdelta = t - mymax(sk, dk);
232 CDR_Test<T, H>::do_test(tdelta, niter, 1,
233 srcbuf, dstbuf,
234 sk, dk);
239 else
241 do_test(total, niter, use_array, srcbuf, dstbuf);
244 delete[] srcbuf;
245 delete[] dstbuf;
248 // Generate an ``interesting'' value for testing at pos >i<.
249 template<class T, class H> T
250 CDR_Test<T, H>::checkval (int i)
252 if (!H::integral ())
254 // If T is not an integral type, we don't want to risk
255 // getting an invalid bit pattern for a T value.
256 return T(i);
258 else
260 T v;
261 unsigned char* s = reinterpret_cast<unsigned char*> ((&v));
262 unsigned int j;
263 for (j = 0; j < H::size (); j++)
265 s[j] = (unsigned char) ((j + i * H::size ()) % 256);
268 return v;
273 // Returns in s an hex representation of T's memory.
274 // (differences in byte order will be noticed in s).
276 // If T = int,
277 // t = 0xaabbccdd,
278 // => s = "aabbccdd" for big endian machines,
279 // s = "ddccbbaa" for little endian machines.
281 template<class T, class H> void
282 CDR_Test<T, H>::ttoh (const T& t, char* s)
284 const unsigned char *const p =
285 reinterpret_cast<const unsigned char*> (&t);
287 static char digits[16] = {
288 '0', '1', '2', '3',
289 '4', '5', '6', '7',
290 '8', '9', 'a', 'b',
291 'c', 'd', 'e', 'f'
294 const unsigned char* q;
295 for (q = p; q < p + H::size (); ++q)
297 int k = *q;
298 *s++ = digits[ k >> 4 ];
299 *s++ = digits[ k & 15 ];
302 *s = 0;
305 void
306 do_seal (char* pos)
308 char* ps = reinterpret_cast<char*> (&seal);
309 pos[0] = ps[0];
310 pos[1] = ps[1];
311 pos[2] = ps[2];
312 pos[3] = ps[3];
316 check_seal (char* pos)
318 char* ps = reinterpret_cast<char*> (&seal);
319 return (pos[0] == ps[0]
320 && pos[1] == ps[1]
321 && pos[2] == ps[2]
322 && pos[3] == ps[3]);
326 // returns the alignment of ptr, wrt ACE_CDR::MAX_ALIGNMENT.
329 tellalign (const char* const ptr)
331 int align = ACE_CDR::MAX_ALIGNMENT;
332 while (ptr != ACE_ptr_align_binary(ptr, align))
334 align = align >> 1;
337 return align;
340 template<class T, class H> void
341 CDR_Test<T, H>::do_test (int total, int niter, int use_array,
342 char* srcbuf, char* dstbuf,
343 int src_offset, int dst_offset)
345 if (!use_array)
347 dst_offset = src_offset = 0;
350 ACE_DEBUG((LM_DEBUG,
351 ACE_TEXT( "Starting Test for %s: %d elements " )
352 ACE_TEXT( "%susing arrays.\n" ),
353 H::name (),
354 total,
355 ((use_array) ? ACE_TEXT( "" ) : ACE_TEXT( "not " ))));
358 if (!use_array && (total % 4) != 0)
360 int lasttotal = total;
361 total -= (total % 4);
362 ACE_DEBUG((LM_DEBUG,
363 ACE_TEXT( "Rounding from %d to %d elements.\n" ),
364 lasttotal,
365 total));
368 char* src = ACE_ptr_align_binary(srcbuf, H::size ());
369 T* idata = reinterpret_cast<T*> (src);
370 idata += src_offset;
371 src = reinterpret_cast<char*> (idata);
374 int i;
375 for (i = 0; i < total; i++)
377 idata[i] = CDR_Test<T, H>::checkval (i);
381 ACE_DEBUG((LM_DEBUG,
382 ACE_TEXT( "Writing data...\n" )));
384 char* toread = 0;
386 ACE_TEST_ASSERT(use_array || total % 4 == 0);
388 double totalsecs = 0.0;
389 int n;
390 for (n = 0; n < niter; n++)
392 size_t size = H::size () * (dst_offset + total) +
393 ACE_CDR::MAX_ALIGNMENT;
394 ACE_OutputCDR os (dstbuf, size);
396 // This is intrusive...
397 char* const end = os.begin ()->wr_ptr() + size;
399 do_seal (end);
401 double secs = 0.0;
402 if (use_array)
405 int i;
406 for (i = 0; i < dst_offset; i++)
408 os << T(0);
412 if (n == 0)
414 ACE_DEBUG((LM_DEBUG,
415 ACE_TEXT ("* src align = %d, dst align = %d\n"),
416 tellalign (src),
417 tellalign (os.begin ()->wr_ptr ())));
420 Crono crono;
421 crono.start ();
422 H::write_array (os, idata, total);
423 crono.stop ();
424 secs = crono.read_seconds ();
426 else
428 int i = 0;
429 for (; i < dst_offset; i++)
431 os << T(0);
433 i = 0;
435 Crono crono;
436 crono.start();
437 while (i < total)
439 os << idata[i++];
440 os << idata[i++];
441 os << idata[i++];
442 os << idata[i++];
443 // static char rs[32 + 1];
444 // CDR_Test<T,H>::ttoh (idata[i], rs);
445 // ACE_DEBUG ((LM_DEBUG, "Write idata[%d] = %s\n", i, rs));
446 // os << idata[i];
447 // i++;
449 crono.stop ();
450 secs = crono.read_seconds ();
453 if (!check_seal(end))
455 ACE_ERROR((LM_ERROR,
456 ACE_TEXT( "Broken seal, aborting.\n" )));
457 ACE_OS::exit(1);
460 totalsecs += secs;
462 if (n == niter - 1)
464 toread = os.begin ()->rd_ptr ();
468 totalsecs = totalsecs / niter;
470 ACE_DEBUG((LM_DEBUG,
471 ACE_TEXT ("Writing to stream %d %s values: %f seconds.\n"),
472 total,
473 H::name (),
474 totalsecs));
478 int i;
479 for (i = 0; i < total; i++)
481 idata[i] = 0;
485 ACE_DEBUG((LM_DEBUG,
486 ACE_TEXT( "Reading them back in opposing byte order...\n" )));
488 const int opposite_byte_order = 1 - ACE_CDR_BYTE_ORDER;
491 double totalsecs = 0.0;
492 int n;
493 for (n = 0; n < niter; n++)
495 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("====== Read iteration %d\n"), n));
497 size_t size = (total + dst_offset) * H::size ();
498 ACE_InputCDR is (toread, size, opposite_byte_order);
500 // This is intrusive...
501 char* const end = is.rd_ptr () + size;
503 do_seal (end);
505 double secs = 0.0;
506 if (use_array)
509 int i;
510 for (i = 0; i < dst_offset; i++)
512 T v;
513 is >> v;
517 if (n == 0)
519 ACE_DEBUG((LM_DEBUG,
520 ACE_TEXT ("* src align = %d, dst align = %d\n"),
521 tellalign (is.rd_ptr ()),
522 tellalign (src)));
525 Crono crono;
526 crono.start ();
527 H::read_array (is, idata, total);
528 crono.stop ();
529 secs = crono.read_seconds ();
531 // Testing for good bit value. Try reading atleast 10
532 // times the size of total. It should fail with good bit
533 // set to 0.
534 H::read_array (is, idata, 10 * total);
536 if (is.good_bit () != 0)
538 ACE_ERROR ((LM_ERROR,
539 ACE_TEXT ("Test for good bit failed in %s Array_test\n"),
540 H::name ()));
543 else
545 int i = 0;
546 Crono crono;
547 crono.start ();
548 while (i < total)
550 #if 0
551 T v;
552 is >> v;
553 static char rs[32 + 1];
554 CDR_Test<T,H>::ttoh (v, rs);
555 ACE_DEBUG ((LM_DEBUG, "Read idata[%d] = %s\n", i, rs));
556 idata[i] = v;
557 i++;
558 #else
559 is >> idata[i++];
560 is >> idata[i++];
561 is >> idata[i++];
562 is >> idata[i++];
563 #endif /* 0 */
565 crono.stop ();
566 secs = crono.read_seconds ();
568 totalsecs += secs;
570 if (!check_seal (end))
572 ACE_ERROR((LM_ERROR,
573 ACE_TEXT( "Broken seal, aborting.\n" )));
574 ACE_OS::exit(1);
578 totalsecs = totalsecs / niter;
580 ACE_DEBUG((LM_DEBUG,
581 ACE_TEXT ("Reading from stream %d %s values")
582 ACE_TEXT (" (byte swapping): %f seconds.\n"),
583 total,
584 H::name (),
585 totalsecs));
588 ACE_DEBUG((LM_DEBUG,
589 ACE_TEXT ("Now checking data...\n") ));
591 int errors = 0;
592 const int maxerrors = 6;
595 int i;
596 for (i = 0; i < total; i++)
598 T rv;
600 const char* src = reinterpret_cast<const char*> ((idata + i));
601 char* dst = reinterpret_cast<char*> ((&rv));
603 H::swap(src, dst);
605 // Due to a "feature" of the gcc 4.1.1 optimizer, we need to do
606 // something with the src pointer so that it doesn't optimize it
607 // away. Calling tellalign() is benign, but the optimizer
608 // doesn't know/care. -- Chad Elliott 1/10/2007
609 tellalign (src);
611 T cv = CDR_Test<T, H>::checkval (i);
612 if (!ACE::is_equal (rv, cv))
614 static char rs[32 + 1];
615 static char cs[32 + 1];
616 CDR_Test<T, H>::ttoh (rv, rs);
617 CDR_Test<T, H>::ttoh (cv, cs);
618 ACE_ERROR((LM_ERROR,
619 ACE_TEXT ( "Wrong value at pos %d:" )
620 ACE_TEXT ( " '%C' should be '%C'.\n" ),
621 i, rs, cs));
622 errors++;
623 if (errors == maxerrors)
625 ACE_ERROR((LM_ERROR,
626 ACE_TEXT ( "%d errors found, ")
627 ACE_TEXT ( "interrupting check.\n" ),
628 errors));
629 break;
635 if (errors != 0)
637 ACE_ERROR((LM_ERROR,
638 ACE_TEXT (" assertion failed: Inconsistencies found (%d), ")
639 ACE_TEXT ("aborting.\n"), errors));
640 ACE_OS::exit(1);
643 ACE_DEBUG((LM_DEBUG,
644 ACE_TEXT ("Data OK, test %s completed.\n"),
645 H::name ()));
648 template <class T, class N>
649 CDR_Test<T, N>::~CDR_Test ()
654 // Helper Clases for the second template parameter of CDR_Test.
655 // One for each tested CDR type.
658 struct DoubleHelper
660 static const ACE_TCHAR* name ()
662 return ACE_TEXT ("CDR::Double");
664 static int integral ()
666 return 0;
668 static void read_array (ACE_InputCDR& is,
669 ACE_CDR::Double* x,
670 ACE_UINT32 n)
672 is.read_double_array (x, n);
674 static void write_array (ACE_OutputCDR& os,
675 ACE_CDR::Double* x,
676 ACE_UINT32 n)
678 os.write_double_array (x, n);
680 static void swap (const char *src, char *dst)
682 ACE_CDR::swap_8 (src, dst);
684 static size_t size ()
686 return sizeof(ACE_CDR::Double);
690 struct FloatHelper
692 static const ACE_TCHAR* name ()
694 return ACE_TEXT ("CDR::Float");
696 static int integral ()
698 return 0;
700 static void read_array (ACE_InputCDR& is,
701 ACE_CDR::Float* x,
702 ACE_UINT32 n)
704 is.read_float_array (x, n);
706 static void write_array (ACE_OutputCDR& os,
707 ACE_CDR::Float* x,
708 ACE_UINT32 n)
710 os.write_float_array (x, n);
712 static void swap (const char *src, char *dst)
714 ACE_CDR::swap_4 (src, dst);
716 static size_t size ()
718 return sizeof(ACE_CDR::Float);
722 struct ShortHelper
724 static const ACE_TCHAR* name ()
726 return ACE_TEXT ("CDR::Short");
728 static int integral ()
730 return 1;
732 static void read_array (ACE_InputCDR& is,
733 ACE_CDR::Short* x,
734 ACE_UINT32 n)
736 is.read_short_array (x, n);
738 static void write_array (ACE_OutputCDR& os,
739 ACE_CDR::Short* x,
740 ACE_UINT32 n)
742 os.write_short_array (x, n);
744 static void swap (const char *src, char *dst)
746 ACE_CDR::swap_2 (src, dst);
748 static size_t size ()
750 return sizeof(ACE_CDR::Short);
754 struct LongHelper
756 static const ACE_TCHAR* name ()
758 return ACE_TEXT ("CDR::Long");
760 static int integral ()
762 return 1;
764 static void read_array (ACE_InputCDR& is,
765 ACE_CDR::Long* x,
766 ACE_UINT32 n)
768 is.read_long_array (x, n);
770 static void write_array (ACE_OutputCDR& os,
771 ACE_CDR::Long* x,
772 ACE_UINT32 n)
774 os.write_long_array (x, n);
776 static void swap (const char *src, char *dst)
778 ACE_CDR::swap_4 (src, dst);
780 static size_t size ()
782 return sizeof(ACE_CDR::Long);
786 struct LongLongHelper
788 static const ACE_TCHAR* name ()
790 return ACE_TEXT ("CDR::LongLong");
792 static int integral ()
794 return 1;
796 static void read_array (ACE_InputCDR& is,
797 ACE_CDR::LongLong* x,
798 ACE_UINT32 n)
800 is.read_longlong_array (x, n);
802 static void write_array (ACE_OutputCDR& os,
803 ACE_CDR::LongLong* x,
804 ACE_UINT32 n)
806 os.write_longlong_array (x, n);
809 static void swap (const char *src, char *dst)
811 ACE_CDR::swap_8 (src, dst);
813 static size_t size ()
815 return sizeof(ACE_CDR::LongLong);
819 struct CharHelper
821 static const ACE_TCHAR* name ()
823 return ACE_TEXT ("CDR::Char");
825 static int integral ()
827 return 1;
829 static void read_array (ACE_InputCDR& is,
830 ACE_CDR::Char* x,
831 ACE_UINT32 n)
833 is.read_char_array (x, n);
835 static void write_array (ACE_OutputCDR& os,
836 ACE_CDR::Char* x,
837 ACE_UINT32 n)
839 os.write_char_array (x, n);
841 static void swap (const char *src, char *dst)
843 *dst = *src;
845 static size_t size ()
847 return sizeof(ACE_CDR::Char);
851 void usage (const ACE_TCHAR* cmd)
853 ACE_ERROR((LM_ERROR,
854 ACE_TEXT ("Usage: %s ")
855 ACE_TEXT ("[-n n] " )
856 ACE_TEXT ("[[-d n|-f n|-q n|-w n|-h n|-c n|-t n] | [-t n]]\n")
857 ACE_TEXT (" -n n: average time for n iterations.\n")
858 ACE_TEXT (" -d n: n double precision floating point\n")
859 ACE_TEXT (" -f n: n single precision floating point\n")
860 ACE_TEXT (" -q n: n quadwords (int64).\n")
861 ACE_TEXT (" -w n: n words (int32).\n")
862 ACE_TEXT (" -h n: n halfwords (int16).\n")
863 ACE_TEXT (" -c n: n chars.\n")
864 ACE_TEXT (" -t n: n iterations for every type.\n")
865 ACE_TEXT (" n must be >= 16 for dfqwhct.\n")
866 ACE_TEXT (" If you provide one of dfqwhc, then only the\n")
867 ACE_TEXT (" test for the corresponding type ")
868 ACE_TEXT ("will be performed.\n"),
869 cmd));
870 ACE_OS::exit(1);
874 validtotal (int n)
876 return n >= 16;
880 validiters (int n)
882 return n > 0;
886 run_main (int argc, ACE_TCHAR *argv[])
888 ACE_START_TEST (ACE_TEXT ("CDR_Array_Test"));
890 ACE_DEBUG ((LM_DEBUG,
891 ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"),
892 ACE::major_version (),
893 ACE::minor_version(),
894 ACE::micro_version()));
896 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("d:f:q:w:h:c:t:n:"));
897 int dtotal = 0;
898 int ftotal = 0;
899 int qtotal = 0;
900 int wtotal = 0;
901 int htotal = 0;
902 int ctotal = 0;
903 int total = 0;
904 int niter = 0;
906 struct { int c; int *v; int (*checkf)(int); } opts[] = {
907 { 'd', &dtotal, validtotal },
908 { 'f', &ftotal, validtotal },
909 { 'q', &qtotal, validtotal },
910 { 'w', &wtotal, validtotal },
911 { 'h', &htotal, validtotal },
912 { 'c', &ctotal, validtotal },
913 { 't', &total, validtotal },
914 { 'n', &niter, validiters },
917 int n = sizeof(opts)/sizeof(opts[0]);
919 int opt;
920 while ((opt = get_opt ()) != EOF)
922 int got = 0;
923 int i;
924 for (i = 0; i < n; i++)
926 if (opts[i].c == opt)
928 int v = ACE_OS::atoi (get_opt.opt_arg ());
929 if (!(opts[i].checkf) (v))
931 usage(ACE_TEXT("CDR_Array_Test"));
934 *(opts[i].v) = v;
935 got = 1;
936 break;
940 if (!got)
942 usage(ACE_TEXT("CDR_Array_Test"));
946 if (total == 0)
948 total = default_total;
951 if (niter == 0)
953 niter = default_niter;
956 if (dtotal == 0
957 && ftotal == 0
958 && qtotal == 0
959 && wtotal == 0
960 && htotal == 0
961 && ctotal == 0)
963 dtotal = ftotal = qtotal = wtotal = htotal = ctotal = total;
966 int use_array;
967 for (use_array = 0; use_array < 2; use_array++)
970 CDR_Test<ACE_CDR::LongLong, LongLongHelper>
971 test (qtotal, niter, use_array);
974 CDR_Test<ACE_CDR::Long, LongHelper>
975 test (wtotal, niter, use_array);
978 CDR_Test<ACE_CDR::Short, ShortHelper>
979 test (htotal, niter, use_array);
982 CDR_Test<ACE_CDR::Char, CharHelper>
983 test (ctotal, niter, use_array);
986 CDR_Test<ACE_CDR::Double, DoubleHelper>
987 test (dtotal, niter, use_array);
990 CDR_Test<ACE_CDR::Float, FloatHelper>
991 test (ftotal, niter, use_array);
995 ACE_END_TEST;
996 return 0;