Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / tests / CDR_Array_Test.cpp
blobed088cf2c2944dbbd6cd7c62583453ff02ba83fd
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
52 // Default number of elements for check buffer, for each tested CDR type.
53 // Be aware that time will be affected by the buffer fitting/not fitting
54 // in the cache (ie, if default_total*sizeof(T) bytes fit in the cache).
55 // Also, you want that your time measuring method has a resolution
56 // compatible with this buffer size, if not you will end up measuring 0.
57 // You can change this value with -t option.
58 static const int default_total = 32*1024;
60 // Repeat this many times for each tested CDR type.
61 // We then take the average time that took for each type and report that.
62 // You can change this value with -n option.
63 static const int default_niter = 10;
66 // A simple cronometer in seconds, that encapsulates our time
67 // measuring method.
69 class Crono {
70 public:
71 Crono() {}
72 ~Crono() {}
73 void start ()
75 #if defined(USE_CLOCK)
76 start_ = clock ();
77 #elif defined(USE_GETRUSAGE)
78 ACE_OS::getrusage (RUSAGE_SELF, &start_);
79 #else
80 timer.start ();
81 #endif
83 void stop ()
85 #if defined(USE_CLOCK)
86 end_ = clock ();
87 #elif defined(USE_GETRUSAGE)
88 ACE_OS::getrusage (RUSAGE_SELF, &end_);
89 #else
90 timer.stop ();
91 #endif
93 double read_seconds ()
95 #if defined(USE_CLOCK)
96 return (end_ - start_) / (double) CLOCKS_PER_SEC;
97 #elif defined(USE_GETRUSAGE)
98 timeval diff;
99 diff.tv_sec = end_.ru_utime.tv_sec - start_.ru_utime.tv_sec;
100 diff.tv_usec = end_.ru_utime.tv_usec - start_.ru_utime.tv_usec;
101 while (diff.tv_usec < 0)
103 --diff.tv_sec;
104 diff.tv_usec += ACE_ONE_SECOND_IN_USECS;
107 return diff.tv_sec + diff.tv_usec / double(ACE_ONE_SECOND_IN_USECS);
108 #else
109 ACE_Time_Value tv;
110 timer.elapsed_time(tv);
111 return tv.usec () / 1000000.0;
112 #endif
114 private:
115 #if defined(USE_CLOCK)
116 clock_t start_;
117 clock_t end_;
118 #elif defined(USE_GETRUSAGE)
119 ACE_Rusage start_;
120 ACE_Rusage end_;
121 #else
122 ACE_High_Res_Timer timer;
123 #endif
127 // Our test, performed in the constructor.
128 // T is one of the CDR types.
129 // H is a helper class (described later).
131 // All this stuff is in a class and not in template functions
132 // to avoid having to deal with potential template function
133 // instantiations problems.
135 template<class T, class H> class CDR_Test
137 public:
138 CDR_Test (int total, int niter, int use_array);
139 static void do_test (int total, int niter, int use_array,
140 char* srcbuf, char* dstbuf,
141 int src_offset = 0, int dst_offset = 0);
142 ~CDR_Test ();
144 static void ttoh (const T& t, char* s);
145 static T checkval(int i);
147 private:
148 CDR_Test (const CDR_Test<T, H>&);
149 CDR_Test<T, H>& operator= (const CDR_Test<T, H>&);
152 static ACE_UINT32 seal = 0xdeadbeef;
154 void
155 zero (char* p, size_t k)
157 char* end = p + k;
158 while (p < end)
160 *p++ = '\0';
164 inline int
165 mymax (int a, int b)
167 return (a >= b) ? a : b;
170 void
171 memabort ()
173 ACE_ERROR((LM_ERROR,
174 ACE_TEXT ("new failed, aborting\n")));
175 ACE_OS::exit (1);
178 template<class T, class H>
179 CDR_Test<T, H>::CDR_Test (int total, int niter, int use_array)
181 if (total <= 0)
183 return ;
186 char* srcbuf;
187 char* dstbuf;
189 const size_t stotal =
190 (total + 10) * H::size () + sizeof(ACE_UINT32) + ACE_CDR::MAX_ALIGNMENT;
192 ACE_NEW(srcbuf, char[stotal]);
193 if (srcbuf == 0)
195 memabort ();
197 zero(srcbuf, stotal);
199 ACE_NEW(dstbuf, char[stotal]);
200 if (dstbuf == 0)
202 memabort ();
204 zero(dstbuf, stotal);
207 if (use_array)
209 // We want to test all the possible loop unrolling deltas.
210 int t;
211 for (t = total - 3; t <= total; t++)
213 int delta;
214 if (sizeof(long) <= H::size ())
216 delta = 1;
218 else
220 delta = (int) (sizeof(long) / H::size ());
223 // We want to test all the posible source/destination buffer
224 // alignment combinations.
225 int sk;
226 for (sk = 0; sk < delta; sk++)
228 int dk;
229 for (dk = 0; dk < delta; dk++)
231 int tdelta = t - mymax(sk, dk);
233 CDR_Test<T, H>::do_test(tdelta, niter, 1,
234 srcbuf, dstbuf,
235 sk, dk);
241 else
243 do_test(total, niter, use_array, srcbuf, dstbuf);
246 delete[] srcbuf;
247 delete[] dstbuf;
250 // Generate an ``interesting'' value for testing at pos >i<.
251 template<class T, class H> T
252 CDR_Test<T, H>::checkval (int i)
254 if (!H::integral ())
256 // If T is not an integral type, we don't want to risk
257 // getting an invalid bit pattern for a T value.
258 return T(i);
260 else
262 T v;
263 unsigned char* s = reinterpret_cast<unsigned char*> ((&v));
264 unsigned int j;
265 for (j = 0; j < H::size (); j++)
267 s[j] = (unsigned char) ((j + i * H::size ()) % 256);
270 return v;
275 // Returns in s an hex representation of T's memory.
276 // (differences in byte order will be noticed in s).
278 // If T = int,
279 // t = 0xaabbccdd,
280 // => s = "aabbccdd" for big endian machines,
281 // s = "ddccbbaa" for little endian machines.
283 template<class T, class H> void
284 CDR_Test<T, H>::ttoh (const T& t, char* s)
286 const unsigned char *const p =
287 reinterpret_cast<const unsigned char*> (&t);
289 static char digits[16] = {
290 '0', '1', '2', '3',
291 '4', '5', '6', '7',
292 '8', '9', 'a', 'b',
293 'c', 'd', 'e', 'f'
296 const unsigned char* q;
297 for (q = p; q < p + H::size (); ++q)
299 int k = *q;
300 *s++ = digits[ k >> 4 ];
301 *s++ = digits[ k & 15 ];
304 *s = 0;
307 void
308 do_seal (char* pos)
310 char* ps = reinterpret_cast<char*> (&seal);
311 pos[0] = ps[0];
312 pos[1] = ps[1];
313 pos[2] = ps[2];
314 pos[3] = ps[3];
318 check_seal (char* pos)
320 char* ps = reinterpret_cast<char*> (&seal);
321 return (pos[0] == ps[0]
322 && pos[1] == ps[1]
323 && pos[2] == ps[2]
324 && pos[3] == ps[3]);
328 // returns the alignment of ptr, wrt ACE_CDR::MAX_ALIGNMENT.
331 tellalign (const char* const ptr)
333 int align = ACE_CDR::MAX_ALIGNMENT;
334 while (ptr != ACE_ptr_align_binary(ptr, align))
336 align = align >> 1;
339 return align;
342 template<class T, class H> void
343 CDR_Test<T, H>::do_test (int total, int niter, int use_array,
344 char* srcbuf, char* dstbuf,
345 int src_offset, int dst_offset)
347 if (!use_array)
349 dst_offset = src_offset = 0;
352 ACE_DEBUG((LM_DEBUG,
353 ACE_TEXT( "Starting Test for %s: %d elements " )
354 ACE_TEXT( "%susing arrays.\n" ),
355 H::name (),
356 total,
357 ((use_array) ? ACE_TEXT( "" ) : ACE_TEXT( "not " ))));
360 if (!use_array && (total % 4) != 0)
362 int lasttotal = total;
363 total -= (total % 4);
364 ACE_DEBUG((LM_DEBUG,
365 ACE_TEXT( "Rounding from %d to %d elements.\n" ),
366 lasttotal,
367 total));
370 char* src = ACE_ptr_align_binary(srcbuf, H::size ());
371 T* idata = reinterpret_cast<T*> (src);
372 idata += src_offset;
373 src = reinterpret_cast<char*> (idata);
376 int i;
377 for (i = 0; i < total; i++)
379 idata[i] = CDR_Test<T, H>::checkval (i);
383 ACE_DEBUG((LM_DEBUG,
384 ACE_TEXT( "Writing data...\n" )));
386 char* toread = 0;
388 ACE_TEST_ASSERT(use_array || total % 4 == 0);
390 double totalsecs = 0.0;
391 int n;
392 for (n = 0; n < niter; n++)
394 size_t size = H::size () * (dst_offset + total) +
395 ACE_CDR::MAX_ALIGNMENT;
396 ACE_OutputCDR os (dstbuf, size);
398 // This is intrusive...
399 char* const end = os.begin ()->wr_ptr() + size;
401 do_seal (end);
403 double secs = 0.0;
404 if (use_array)
407 int i;
408 for (i = 0; i < dst_offset; i++)
410 os << T(0);
414 if (n == 0)
416 ACE_DEBUG((LM_DEBUG,
417 ACE_TEXT ("* src align = %d, dst align = %d\n"),
418 tellalign (src),
419 tellalign (os.begin ()->wr_ptr ())));
422 Crono crono;
423 crono.start ();
424 H::write_array (os, idata, total);
425 crono.stop ();
426 secs = crono.read_seconds ();
428 else
430 int i = 0;
431 for (; i < dst_offset; i++)
433 os << T(0);
435 i = 0;
437 Crono crono;
438 crono.start();
439 while (i < total)
441 os << idata[i++];
442 os << idata[i++];
443 os << idata[i++];
444 os << idata[i++];
445 // static char rs[32 + 1];
446 // CDR_Test<T,H>::ttoh (idata[i], rs);
447 // ACE_DEBUG ((LM_DEBUG, "Write idata[%d] = %s\n", i, rs));
448 // os << idata[i];
449 // i++;
451 crono.stop ();
452 secs = crono.read_seconds ();
455 if (!check_seal(end))
457 ACE_ERROR((LM_ERROR,
458 ACE_TEXT( "Broken seal, aborting.\n" )));
459 ACE_OS::exit(1);
462 totalsecs += secs;
464 if (n == niter - 1)
466 toread = os.begin ()->rd_ptr ();
470 totalsecs = totalsecs / niter;
472 ACE_DEBUG((LM_DEBUG,
473 ACE_TEXT ("Writing to stream %d %s values: %f seconds.\n"),
474 total,
475 H::name (),
476 totalsecs));
480 int i;
481 for (i = 0; i < total; i++)
483 idata[i] = 0;
487 ACE_DEBUG((LM_DEBUG,
488 ACE_TEXT( "Reading them back in opposing byte order...\n" )));
490 const int opposite_byte_order = 1 - ACE_CDR_BYTE_ORDER;
493 double totalsecs = 0.0;
494 int n;
495 for (n = 0; n < niter; n++)
497 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("====== Read iteration %d\n"), n));
499 size_t size = (total + dst_offset) * H::size ();
500 ACE_InputCDR is (toread, size, opposite_byte_order);
502 // This is intrusive...
503 char* const end = is.rd_ptr () + size;
505 do_seal (end);
507 double secs = 0.0;
508 if (use_array)
511 int i;
512 for (i = 0; i < dst_offset; i++)
514 T v;
515 is >> v;
519 if (n == 0)
521 ACE_DEBUG((LM_DEBUG,
522 ACE_TEXT ("* src align = %d, dst align = %d\n"),
523 tellalign (is.rd_ptr ()),
524 tellalign (src)));
527 Crono crono;
528 crono.start ();
529 H::read_array (is, idata, total);
530 crono.stop ();
531 secs = crono.read_seconds ();
533 // Testing for good bit value. Try reading atleast 10
534 // times the size of total. It should fail with good bit
535 // set to 0.
536 H::read_array (is, idata, 10 * total);
538 if (is.good_bit () != 0)
540 ACE_ERROR ((LM_ERROR,
541 ACE_TEXT ("Test for good bit failed in %s Array_test\n"),
542 H::name ()));
545 else
547 int i = 0;
548 Crono crono;
549 crono.start ();
550 while (i < total)
552 #if 0
553 T v;
554 is >> v;
555 static char rs[32 + 1];
556 CDR_Test<T,H>::ttoh (v, rs);
557 ACE_DEBUG ((LM_DEBUG, "Read idata[%d] = %s\n", i, rs));
558 idata[i] = v;
559 i++;
560 #else
561 is >> idata[i++];
562 is >> idata[i++];
563 is >> idata[i++];
564 is >> idata[i++];
565 #endif /* 0 */
567 crono.stop ();
568 secs = crono.read_seconds ();
570 totalsecs += secs;
572 if (!check_seal (end))
574 ACE_ERROR((LM_ERROR,
575 ACE_TEXT( "Broken seal, aborting.\n" )));
576 ACE_OS::exit(1);
580 totalsecs = totalsecs / niter;
582 ACE_DEBUG((LM_DEBUG,
583 ACE_TEXT ("Reading from stream %d %s values")
584 ACE_TEXT (" (byte swapping): %f seconds.\n"),
585 total,
586 H::name (),
587 totalsecs));
590 ACE_DEBUG((LM_DEBUG,
591 ACE_TEXT ("Now checking data...\n") ));
593 int errors = 0;
594 const int maxerrors = 6;
597 int i;
598 for (i = 0; i < total; i++)
600 T rv;
602 const char* src = reinterpret_cast<const char*> ((idata + i));
603 char* dst = reinterpret_cast<char*> ((&rv));
605 H::swap(src, dst);
607 // Due to a "feature" of the gcc 4.1.1 optimizer, we need to do
608 // something with the src pointer so that it doesn't optimize it
609 // away. Calling tellalign() is benign, but the optimizer
610 // doesn't know/care. -- Chad Elliott 1/10/2007
611 tellalign (src);
613 T cv = CDR_Test<T, H>::checkval (i);
614 if (!ACE::is_equal (rv, cv))
616 static char rs[32 + 1];
617 static char cs[32 + 1];
618 CDR_Test<T, H>::ttoh (rv, rs);
619 CDR_Test<T, H>::ttoh (cv, cs);
620 ACE_ERROR((LM_ERROR,
621 ACE_TEXT ( "Wrong value at pos %d:" )
622 ACE_TEXT ( " '%C' should be '%C'.\n" ),
623 i, rs, cs));
624 errors++;
625 if (errors == maxerrors)
627 ACE_ERROR((LM_ERROR,
628 ACE_TEXT ( "%d errors found, ")
629 ACE_TEXT ( "interrupting check.\n" ),
630 errors));
631 break;
637 if (errors != 0)
639 ACE_ERROR((LM_ERROR,
640 ACE_TEXT (" assertion failed: Inconsistencies found (%d), ")
641 ACE_TEXT ("aborting.\n"), errors));
642 ACE_OS::exit(1);
645 ACE_DEBUG((LM_DEBUG,
646 ACE_TEXT ("Data OK, test %s completed.\n"),
647 H::name ()));
650 template <class T, class N>
651 CDR_Test<T, N>::~CDR_Test ()
656 // Helper Clases for the second template parameter of CDR_Test.
657 // One for each tested CDR type.
660 struct DoubleHelper
662 static const ACE_TCHAR* name ()
664 return ACE_TEXT ("CDR::Double");
666 static int integral ()
668 return 0;
670 static void read_array (ACE_InputCDR& is,
671 ACE_CDR::Double* x,
672 ACE_UINT32 n)
674 is.read_double_array (x, n);
676 static void write_array (ACE_OutputCDR& os,
677 ACE_CDR::Double* x,
678 ACE_UINT32 n)
680 os.write_double_array (x, n);
682 static void swap (const char *src, char *dst)
684 ACE_CDR::swap_8 (src, dst);
686 static size_t size ()
688 return sizeof(ACE_CDR::Double);
692 struct FloatHelper
694 static const ACE_TCHAR* name ()
696 return ACE_TEXT ("CDR::Float");
698 static int integral ()
700 return 0;
702 static void read_array (ACE_InputCDR& is,
703 ACE_CDR::Float* x,
704 ACE_UINT32 n)
706 is.read_float_array (x, n);
708 static void write_array (ACE_OutputCDR& os,
709 ACE_CDR::Float* x,
710 ACE_UINT32 n)
712 os.write_float_array (x, n);
714 static void swap (const char *src, char *dst)
716 ACE_CDR::swap_4 (src, dst);
718 static size_t size ()
720 return sizeof(ACE_CDR::Float);
724 struct ShortHelper
726 static const ACE_TCHAR* name ()
728 return ACE_TEXT ("CDR::Short");
730 static int integral ()
732 return 1;
734 static void read_array (ACE_InputCDR& is,
735 ACE_CDR::Short* x,
736 ACE_UINT32 n)
738 is.read_short_array (x, n);
740 static void write_array (ACE_OutputCDR& os,
741 ACE_CDR::Short* x,
742 ACE_UINT32 n)
744 os.write_short_array (x, n);
746 static void swap (const char *src, char *dst)
748 ACE_CDR::swap_2 (src, dst);
750 static size_t size ()
752 return sizeof(ACE_CDR::Short);
756 struct LongHelper
758 static const ACE_TCHAR* name ()
760 return ACE_TEXT ("CDR::Long");
762 static int integral ()
764 return 1;
766 static void read_array (ACE_InputCDR& is,
767 ACE_CDR::Long* x,
768 ACE_UINT32 n)
770 is.read_long_array (x, n);
772 static void write_array (ACE_OutputCDR& os,
773 ACE_CDR::Long* x,
774 ACE_UINT32 n)
776 os.write_long_array (x, n);
778 static void swap (const char *src, char *dst)
780 ACE_CDR::swap_4 (src, dst);
782 static size_t size ()
784 return sizeof(ACE_CDR::Long);
788 struct LongLongHelper
790 static const ACE_TCHAR* name ()
792 return ACE_TEXT ("CDR::LongLong");
794 static int integral ()
796 return 1;
798 static void read_array (ACE_InputCDR& is,
799 ACE_CDR::LongLong* x,
800 ACE_UINT32 n)
802 is.read_longlong_array (x, n);
804 static void write_array (ACE_OutputCDR& os,
805 ACE_CDR::LongLong* x,
806 ACE_UINT32 n)
808 os.write_longlong_array (x, n);
811 static void swap (const char *src, char *dst)
813 ACE_CDR::swap_8 (src, dst);
815 static size_t size ()
817 return sizeof(ACE_CDR::LongLong);
821 struct CharHelper
823 static const ACE_TCHAR* name ()
825 return ACE_TEXT ("CDR::Char");
827 static int integral ()
829 return 1;
831 static void read_array (ACE_InputCDR& is,
832 ACE_CDR::Char* x,
833 ACE_UINT32 n)
835 is.read_char_array (x, n);
837 static void write_array (ACE_OutputCDR& os,
838 ACE_CDR::Char* x,
839 ACE_UINT32 n)
841 os.write_char_array (x, n);
843 static void swap (const char *src, char *dst)
845 *dst = *src;
847 static size_t size ()
849 return sizeof(ACE_CDR::Char);
853 void usage (const ACE_TCHAR* cmd)
855 ACE_ERROR((LM_ERROR,
856 ACE_TEXT ("Usage: %s ")
857 ACE_TEXT ("[-n n] " )
858 ACE_TEXT ("[[-d n|-f n|-q n|-w n|-h n|-c n|-t n] | [-t n]]\n")
859 ACE_TEXT (" -n n: average time for n iterations.\n")
860 ACE_TEXT (" -d n: n double precision floating point\n")
861 ACE_TEXT (" -f n: n single precision floating point\n")
862 ACE_TEXT (" -q n: n quadwords (int64).\n")
863 ACE_TEXT (" -w n: n words (int32).\n")
864 ACE_TEXT (" -h n: n halfwords (int16).\n")
865 ACE_TEXT (" -c n: n chars.\n")
866 ACE_TEXT (" -t n: n iterations for every type.\n")
867 ACE_TEXT (" n must be >= 16 for dfqwhct.\n")
868 ACE_TEXT (" If you provide one of dfqwhc, then only the\n")
869 ACE_TEXT (" test for the corresponding type ")
870 ACE_TEXT ("will be performed.\n"),
871 cmd));
872 ACE_OS::exit(1);
876 validtotal (int n)
878 return n >= 16;
882 validiters (int n)
884 return n > 0;
888 run_main (int argc, ACE_TCHAR *argv[])
890 ACE_START_TEST (ACE_TEXT ("CDR_Array_Test"));
892 ACE_DEBUG ((LM_DEBUG,
893 ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"),
894 ACE::major_version (),
895 ACE::minor_version(),
896 ACE::beta_version()));
898 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("d:f:q:w:h:c:t:n:"));
899 int dtotal = 0;
900 int ftotal = 0;
901 int qtotal = 0;
902 int wtotal = 0;
903 int htotal = 0;
904 int ctotal = 0;
905 int total = 0;
906 int niter = 0;
908 struct { int c; int *v; int (*checkf)(int); } opts[] = {
909 { 'd', &dtotal, validtotal },
910 { 'f', &ftotal, validtotal },
911 { 'q', &qtotal, validtotal },
912 { 'w', &wtotal, validtotal },
913 { 'h', &htotal, validtotal },
914 { 'c', &ctotal, validtotal },
915 { 't', &total, validtotal },
916 { 'n', &niter, validiters },
919 int n = sizeof(opts)/sizeof(opts[0]);
921 int opt;
922 while ((opt = get_opt ()) != EOF)
924 int got = 0;
925 int i;
926 for (i = 0; i < n; i++)
928 if (opts[i].c == opt)
930 int v = ACE_OS::atoi (get_opt.opt_arg ());
931 if (!(opts[i].checkf) (v))
933 usage(ACE_TEXT("CDR_Array_Test"));
936 *(opts[i].v) = v;
937 got = 1;
938 break;
942 if (!got)
944 usage(ACE_TEXT("CDR_Array_Test"));
948 if (total == 0)
950 total = default_total;
953 if (niter == 0)
955 niter = default_niter;
958 if (dtotal == 0
959 && ftotal == 0
960 && qtotal == 0
961 && wtotal == 0
962 && htotal == 0
963 && ctotal == 0)
965 dtotal = ftotal = qtotal = wtotal = htotal = ctotal = total;
968 int use_array;
969 for (use_array = 0; use_array < 2; use_array++)
972 CDR_Test<ACE_CDR::LongLong, LongLongHelper>
973 test (qtotal, niter, use_array);
976 CDR_Test<ACE_CDR::Long, LongHelper>
977 test (wtotal, niter, use_array);
980 CDR_Test<ACE_CDR::Short, ShortHelper>
981 test (htotal, niter, use_array);
984 CDR_Test<ACE_CDR::Char, CharHelper>
985 test (ctotal, niter, use_array);
988 CDR_Test<ACE_CDR::Double, DoubleHelper>
989 test (dtotal, niter, use_array);
992 CDR_Test<ACE_CDR::Float, FloatHelper>
993 test (ftotal, niter, use_array);
997 ACE_END_TEST;
998 return 0;