2 * @file Bounded_String.cpp
4 * @brief test for STL iterator behaviour of CORBA bounded string sequence
6 * @author Friedhelm Wolf (fwolf@dre.vanderbilt.edu)
9 #include "tao/Bounded_Basic_String_Sequence_T.h"
10 #include "tao/CORBA_String.h"
11 #include "ace/Log_Msg.h"
12 #include "ace/OS_NS_string.h"
18 #if defined TAO_HAS_SEQUENCE_ITERATORS && TAO_HAS_SEQUENCE_ITERATORS == 1
20 typedef TAO::bounded_basic_string_sequence
<char, 4> s_sequence
;
22 #define FAIL_RETURN_IF(CONDITION) \
25 ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \
29 template <typename ITERATOR_T
>
34 // test equality operator
35 FAIL_RETURN_IF (!(a
.begin () == a
.begin ()));
37 // test non-equality operator
38 FAIL_RETURN_IF (a
.end () != a
.end ());
40 // test for correct behaviour for empty sequence
41 FAIL_RETURN_IF (a
.begin() != a
.end ());
43 // setup of an example sequence
46 const char * elem0_cstr
= "elem0";
47 const char * elem1_cstr
= "elem1";
48 const char * elem2_cstr
= "elem2";
49 const char * elem3_cstr
= "elem3";
51 a
[0] = CORBA::string_dup (elem0_cstr
);
52 a
[1] = CORBA::string_dup (elem1_cstr
);
53 a
[2] = CORBA::string_dup (elem2_cstr
);
54 a
[3] = CORBA::string_dup (elem3_cstr
);
56 // test iterator copy constructor
57 ITERATOR_T
a_it (a
.begin ());
58 FAIL_RETURN_IF (a_it
!= a
.begin ());
60 // test assignment operator
62 FAIL_RETURN_IF (a_it
!= a
.begin ());
64 // test non const dereferencing
65 // JWH2 - I don't think this test makes sense. I believe the compiler
66 // will always return a const value since the dereference is on
67 // the right hand side of the assignment (i.e., r value).
68 //char* value0 = *a_it;
69 //FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem0_cstr) != 0);
71 // test const dereferencing
72 const char* const value1
= *a_it
;
73 FAIL_RETURN_IF (ACE_OS::strcmp (value1
, elem0_cstr
) != 0);
75 // test increment operation
77 FAIL_RETURN_IF (a_it
== a
.begin());
78 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem1_cstr
) != 0);
81 FAIL_RETURN_IF (!(a
.begin () < a_it
));
82 FAIL_RETURN_IF (a_it
< a
.begin ());
84 // test difference type
85 int a_diff
= a_it
- a
.begin ();
86 FAIL_RETURN_IF (a_diff
!= 1);
88 // test copy constructor
89 ITERATOR_T
a_it1 (a_it
);
90 FAIL_RETURN_IF (a_it1
!= a_it
);
92 // test preincrement operator
94 FAIL_RETURN_IF ((a_it1
- a_it
) != 1);
96 // test = and += operator
97 ITERATOR_T a_it2
= a_it
+= 3;
98 FAIL_RETURN_IF (a_it2
!= a_it
);
99 FAIL_RETURN_IF ((a_it
- a_it1
) != 2);
103 FAIL_RETURN_IF ((a_it2
- a_it1
) != 3);
105 // test post-decrement operation
108 FAIL_RETURN_IF (a_it
== a
.end ());
109 FAIL_RETURN_IF ((a
.end () - a_it
) != 1);
110 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem3_cstr
) != 0);
112 // test pre-decrement operator
115 FAIL_RETURN_IF (a_it
== a
.end ());
116 FAIL_RETURN_IF ((a
.end () - a_it
) != 1);
117 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem3_cstr
) != 0);
121 FAIL_RETURN_IF ((a_it1
- a_it
) != 2);
125 FAIL_RETURN_IF ((a_it1
- a_it2
) != 2);
127 // test operator[] read
129 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[0]) != 0);
131 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[2]) != 0);
133 // test operator[] write
134 // NOTE: This now changes the sequence a.
135 // NOTE: This does not work for const_iterators which are
136 // sometimes used in this function.
137 // a_it[0] = CORBA::string_dup (elem0_cstr);
138 // FAIL_RETURN_IF (ACE_OS::strcmp (a[2],elem0_cstr) != 0);
140 // reset content of sequence a
141 //a[2] = CORBA::string_dup (elem2_cstr);
143 // test for loop behaviour
145 ITERATOR_T b_it
= b
.begin ();
147 for (a_it
= a
.begin ();
151 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, *b_it
) != 0);
157 std::copy (a
.begin (),
161 FAIL_RETURN_IF (test
.length () != a
.length ());
163 ITERATOR_T copytest_iter
= test
.begin ();
164 for (ITERATOR_T copya_iter
= a
.begin ();
165 copya_iter
!= a
.end ();
166 ++copya_iter
, ++copytest_iter
)
168 FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter
, *copytest_iter
) != 0);
171 /// Testing - using ostream_iterator
172 std::ostringstream ostream
;
173 std::copy (a
.begin (),
175 // JWH2 - I changed value_type to const_value_type. Is that
176 // the correct approach?
177 std::ostream_iterator
<s_sequence::const_value_type
> (ostream
,
181 ostream
.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0);
186 //-----------------------------------------------------------------------------
188 template <typename ITERATOR_T
>
189 int test_const_sequence ()
191 // setup of an example sequence
195 const char * elem0_cstr
= "elem0";
196 const char * elem1_cstr
= "elem1";
197 const char * elem2_cstr
= "elem2";
198 const char * elem3_cstr
= "elem3";
200 setup
[0] = CORBA::string_dup (elem0_cstr
);
201 setup
[1] = CORBA::string_dup (elem1_cstr
);
202 setup
[2] = CORBA::string_dup (elem2_cstr
);
203 setup
[3] = CORBA::string_dup (elem3_cstr
);
205 const s_sequence a
= setup
;
207 // test equality operator
208 FAIL_RETURN_IF (!(a
.begin () == a
.begin ()));
210 // test non-equality operator
211 FAIL_RETURN_IF (a
.end () != a
.end ());
213 // test iterator copy constructor
214 ITERATOR_T
a_it (a
.begin ());
215 FAIL_RETURN_IF (a_it
!= a
.begin ());
217 // test assignment operator
219 FAIL_RETURN_IF (a_it
!= a
.begin ());
221 // test non const dereferencing
222 // JWH2 - I don't think this test makes sense. I believe the compiler
223 // will always return a const value since the dereference is on
224 // the right hand side of the assignment (i.e., r value).
225 //char* value0 = *a_it;
226 //FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem0_cstr) != 0);
228 // test const dereferencing
229 const char* const value1
= *a_it
;
230 FAIL_RETURN_IF (ACE_OS::strcmp (value1
, elem0_cstr
) != 0);
232 // test increment operation
234 FAIL_RETURN_IF (a_it
== a
.begin());
235 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem1_cstr
) != 0);
238 FAIL_RETURN_IF (!(a
.begin () < a_it
));
239 FAIL_RETURN_IF (a_it
< a
.begin ());
241 // test difference type
242 int a_diff
= a_it
- a
.begin ();
243 FAIL_RETURN_IF (a_diff
!= 1);
245 // test copy constructor
246 ITERATOR_T
a_it1 (a_it
);
247 FAIL_RETURN_IF (a_it1
!= a_it
);
249 // test preincrement operator
251 FAIL_RETURN_IF ((a_it1
- a_it
) != 1);
253 // test = and += operator
254 ITERATOR_T a_it2
= a_it
+= 3;
255 FAIL_RETURN_IF (a_it2
!= a_it
);
256 FAIL_RETURN_IF ((a_it
- a_it1
) != 2);
260 FAIL_RETURN_IF ((a_it2
- a_it1
) != 3);
262 // test post-decrement operation
265 FAIL_RETURN_IF (a_it
== a
.end ());
266 FAIL_RETURN_IF ((a
.end () - a_it
) != 1);
267 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem3_cstr
) != 0);
269 // test pre-decrement operator
272 FAIL_RETURN_IF (a_it
== a
.end ());
273 FAIL_RETURN_IF ((a
.end () - a_it
) != 1);
274 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem3_cstr
) != 0);
278 FAIL_RETURN_IF ((a_it1
- a_it
) != 2);
282 FAIL_RETURN_IF ((a_it1
- a_it2
) != 2);
284 // test operator[] read
286 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[0]) != 0);
288 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[2]) != 0);
290 // test for loop behaviour
292 ITERATOR_T b_it
= b
.begin ();
294 for (a_it
= a
.begin ();
298 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, *b_it
) != 0);
304 std::copy (a
.begin (),
308 FAIL_RETURN_IF (test
.length () != a
.length ());
310 ITERATOR_T copytest_iter
= test
.begin ();
311 for (ITERATOR_T copya_iter
= a
.begin ();
312 copya_iter
!= a
.end ();
313 ++copya_iter
, ++copytest_iter
)
315 FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter
, *copytest_iter
) != 0);
318 /// Testing - using ostream_iterator
319 std::ostringstream ostream
;
320 std::copy (a
.begin (),
322 // JWH2 - I changed value_type to const_value_type. Is that
323 // the correct approach?
324 std::ostream_iterator
<s_sequence::const_value_type
> (ostream
,
328 ostream
.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0);
333 //-----------------------------------------------------------------------------
335 template <typename REVERSE_ITERATOR_T
>
336 int test_sequence_reverse ()
340 // test equality operator
341 FAIL_RETURN_IF (!(a
.begin () == a
.begin ()));
343 // test non-equality operator
344 FAIL_RETURN_IF (a
.end () != a
.end ());
346 // test for correct behaviour for empty sequence
348 FAIL_RETURN_IF (a
.begin() != a
.end ());
350 // setup of an example sequence
353 const char * elem0_cstr
= "elem0";
354 const char * elem1_cstr
= "elem1";
355 const char * elem2_cstr
= "elem2";
356 const char * elem3_cstr
= "elem3";
359 a
[0] = CORBA::string_dup (elem0_cstr
);
360 a
[1] = CORBA::string_dup (elem1_cstr
);
361 a
[2] = CORBA::string_dup (elem2_cstr
);
362 a
[3] = CORBA::string_dup (elem3_cstr
);
364 // test iterator copy constructor
365 REVERSE_ITERATOR_T
a_it (a
.rbegin ());
366 FAIL_RETURN_IF (a_it
!= a
.rbegin ());
368 // test assignment operator
370 FAIL_RETURN_IF (a_it
!= a
.rbegin ());
372 // test non const dereferencing
373 // JWH2 - I don't think this test makes sense. I believe the compiler
374 // will always return a const value since the dereference is on
375 // the right hand side of the assignment (i.e., r value).
376 //char* value0 = *a_it;
377 //FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem3_cstr) != 0);
379 // test const dereferencing
380 const char* const value1
= *a_it
;
381 FAIL_RETURN_IF (ACE_OS::strcmp (value1
, elem3_cstr
) != 0);
383 // test increment operation
385 FAIL_RETURN_IF (a_it
== a
.rbegin());
386 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem2_cstr
) != 0);
389 FAIL_RETURN_IF (!(a
.rbegin () < a_it
));
390 FAIL_RETURN_IF (a_it
< a
.rbegin ());
392 // test difference type
393 int a_diff
= a_it
- a
.rbegin ();
394 FAIL_RETURN_IF (a_diff
!= 1);
396 // test copy constructor
397 REVERSE_ITERATOR_T
a_it1 (a_it
);
398 FAIL_RETURN_IF (a_it1
!= a_it
);
400 // test preincrement operator
402 FAIL_RETURN_IF ((a_it1
- a_it
) != 1);
404 // test = and += operator
405 REVERSE_ITERATOR_T a_it2
= a_it
+= 3;
406 FAIL_RETURN_IF (a_it2
!= a_it
);
407 FAIL_RETURN_IF ((a_it
- a_it1
) != 2);
411 FAIL_RETURN_IF ((a_it2
- a_it1
) != 3);
413 // test post-decrement operation
416 FAIL_RETURN_IF (a_it
== a
.rend ());
417 FAIL_RETURN_IF ((a
.rend () - a_it
) != 1);
418 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem0_cstr
) != 0);
420 // test pre-decrement operator
423 FAIL_RETURN_IF (a_it
== a
.rend ());
424 FAIL_RETURN_IF ((a
.rend () - a_it
) != 1);
425 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem0_cstr
) != 0);
429 FAIL_RETURN_IF ((a_it1
- a_it
) != 2);
433 FAIL_RETURN_IF ((a_it1
- a_it2
) != 2);
435 // test operator[] read
437 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[3]) != 0);
439 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[1]) != 0);
441 // test operator[] write
442 // NOTE: This now changes the sequence a.
443 // this is not possible for const iterators which are
444 // sometimes used by this function.
445 // a_it[0] = CORBA::string_dup (elem0_cstr);
446 // FAIL_RETURN_IF (ACE_OS::strcmp (a[1],elem0_cstr) != 0);
448 // reset content of sequence a
449 //a[1] = CORBA::string_dup (elem1_cstr);
451 // test for loop behaviour
453 REVERSE_ITERATOR_T b_it
= b
.rbegin ();
455 for (a_it
= a
.rbegin ();
459 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, *b_it
) != 0);
463 test
.length (a
.length ());
465 std::copy (a
.begin (),
469 FAIL_RETURN_IF (test
.length () != a
.length ());
471 REVERSE_ITERATOR_T copytest_iter
= test
.rbegin ();
472 for (REVERSE_ITERATOR_T copya_iter
= a
.rbegin ();
473 copya_iter
!= a
.rend ();
474 ++copya_iter
, ++copytest_iter
)
476 FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter
, *copytest_iter
) != 0);
479 /// Testing - using ostream_iterator
480 std::ostringstream ostream
;
481 std::copy (a
.rbegin (),
483 // JWH2 - I changed value_type to const_value_type. Is that
484 // the correct approach?
485 std::ostream_iterator
<s_sequence::const_value_type
> (ostream
,
489 ostream
.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0);
494 //-----------------------------------------------------------------------------
496 template <typename REVERSE_ITERATOR_T
>
497 int test_const_sequence_reverse ()
499 // setup of an example sequence
503 const char * elem0_cstr
= "elem0";
504 const char * elem1_cstr
= "elem1";
505 const char * elem2_cstr
= "elem2";
506 const char * elem3_cstr
= "elem3";
508 setup
[0] = CORBA::string_dup (elem0_cstr
);
509 setup
[1] = CORBA::string_dup (elem1_cstr
);
510 setup
[2] = CORBA::string_dup (elem2_cstr
);
511 setup
[3] = CORBA::string_dup (elem3_cstr
);
513 const s_sequence a
= setup
;
515 // test equality operator
516 FAIL_RETURN_IF (!(a
.begin () == a
.begin ()));
518 // test non-equality operator
519 FAIL_RETURN_IF (a
.end () != a
.end ());
521 // test iterator copy constructor
522 REVERSE_ITERATOR_T
a_it (a
.rbegin ());
523 FAIL_RETURN_IF (a_it
!= a
.rbegin ());
525 // test assignment operator
527 FAIL_RETURN_IF (a_it
!= a
.rbegin ());
529 // test non const dereferencing
530 // JWH2 - I don't think this test makes sense. I believe the compiler
531 // will always return a const value since the dereference is on
532 // the right hand side of the assignment (i.e., r value).
533 //char* value0 = *a_it;
534 //FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem3_cstr) != 0);
536 // test const dereferencing
537 const char* const value1
= *a_it
;
538 FAIL_RETURN_IF (ACE_OS::strcmp (value1
, elem3_cstr
) != 0);
540 // test increment operation
542 FAIL_RETURN_IF (a_it
== a
.rbegin());
543 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem2_cstr
) != 0);
546 FAIL_RETURN_IF (!(a
.rbegin () < a_it
));
547 FAIL_RETURN_IF (a_it
< a
.rbegin ());
549 // test difference type
550 int a_diff
= a_it
- a
.rbegin ();
551 FAIL_RETURN_IF (a_diff
!= 1);
553 // test copy constructor
554 REVERSE_ITERATOR_T
a_it1 (a_it
);
555 FAIL_RETURN_IF (a_it1
!= a_it
);
557 // test preincrement operator
559 FAIL_RETURN_IF ((a_it1
- a_it
) != 1);
561 // test = and += operator
562 REVERSE_ITERATOR_T a_it2
= a_it
+= 3;
563 FAIL_RETURN_IF (a_it2
!= a_it
);
564 FAIL_RETURN_IF ((a_it
- a_it1
) != 2);
568 FAIL_RETURN_IF ((a_it2
- a_it1
) != 3);
570 // test post-decrement operation
573 FAIL_RETURN_IF (a_it
== a
.rend ());
574 FAIL_RETURN_IF ((a
.rend () - a_it
) != 1);
575 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem0_cstr
) != 0);
577 // test pre-decrement operator
580 FAIL_RETURN_IF (a_it
== a
.rend ());
581 FAIL_RETURN_IF ((a
.rend () - a_it
) != 1);
582 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, elem0_cstr
) != 0);
586 FAIL_RETURN_IF ((a_it1
- a_it
) != 2);
590 FAIL_RETURN_IF ((a_it1
- a_it2
) != 2);
592 // test operator[] read
594 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[3]) != 0);
596 FAIL_RETURN_IF (ACE_OS::strcmp (a_it
[0],a
[1]) != 0);
598 // test for loop behaviour
600 REVERSE_ITERATOR_T b_it
= b
.rbegin ();
602 for (a_it
= a
.rbegin ();
606 FAIL_RETURN_IF (ACE_OS::strcmp (*a_it
, *b_it
) != 0);
610 test
.length (a
.length ());
612 std::copy (a
.begin (),
616 FAIL_RETURN_IF (test
.length () != a
.length ());
618 REVERSE_ITERATOR_T copytest_iter
= test
.rbegin ();
619 for (REVERSE_ITERATOR_T copya_iter
= a
.rbegin ();
620 copya_iter
!= a
.rend ();
621 ++copya_iter
, ++copytest_iter
)
623 FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter
, *copytest_iter
) != 0);
626 /// Testing - using ostream_iterator
627 std::ostringstream ostream
;
628 std::copy (a
.rbegin (),
630 // JWH2 - I changed value_type to const_value_type. Is that
631 // the correct approach?
632 std::ostream_iterator
<s_sequence::const_value_type
> (ostream
,
636 ostream
.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0);
643 //-----------------------------------------------------------------------------
645 int ACE_TMAIN(int,ACE_TCHAR
*[])
649 #if defined TAO_HAS_SEQUENCE_ITERATORS && TAO_HAS_SEQUENCE_ITERATORS == 1
651 // Test Generic_Sequence_Iterator.
652 status
+= test_sequence
<s_sequence::iterator
> ();
654 // Test Const_Generic_Sequence_Iterator with non-const sequence.
655 status
+= test_sequence
<s_sequence::const_iterator
> ();
657 // Test Const_Generic_Sequence_Iterator with const sequence.
658 status
+= test_const_sequence
<s_sequence::const_iterator
> ();
660 // Test Generic_Sequence_Reverse_Iterator.
661 status
+= test_sequence_reverse
<s_sequence::reverse_iterator
> ();
663 // Test Const_Generic_Sequence_Reverse_Iterator with non-const sequence.
664 status
+= test_sequence_reverse
<s_sequence::const_reverse_iterator
> ();
666 // Test Const_Generic_Sequence_Reverse_Iterator with const sequence.
667 status
+= test_const_sequence_reverse
<s_sequence::const_reverse_iterator
> ();