diff options
Diffstat (limited to 'TAO/tests/Sequence_Iterators/StringSeq.cpp')
-rw-r--r-- | TAO/tests/Sequence_Iterators/StringSeq.cpp | 961 |
1 files changed, 961 insertions, 0 deletions
diff --git a/TAO/tests/Sequence_Iterators/StringSeq.cpp b/TAO/tests/Sequence_Iterators/StringSeq.cpp new file mode 100644 index 00000000000..639c0ff6196 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/StringSeq.cpp @@ -0,0 +1,961 @@ +/** + * @file StringSeq.cpp + * + * @brief test for STL iterator behaviour of CORBA unbounded string sequence + * + * $Id$ + * + * @author Friedhelm Wolf (fwolf@dre.vanderbilt.edu) + */ + +#include "tao/StringSeqC.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" + +#include <iostream> +#include <iterator> +#include <sstream> + +#define FAIL_RETURN_IF(CONDITION) \ + if (CONDITION) \ + { \ + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \ + return 1; \ + } + +//----------------------------------------------------------------------------- + +#if defined TAO_HAS_SEQUENCE_ITERATORS && TAO_HAS_SEQUENCE_ITERATORS == 1 + +template <typename ITERATOR_T> +int test_sequence () +{ + ::CORBA::StringSeq a; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test for correct behaviour for empty sequence + + FAIL_RETURN_IF (a.begin() != a.end ()); + + // setup of an example sequence + + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + a.length (4); + // Create a case to test for memory leaks + // in the sequence. + a[0] = CORBA::string_dup (elem0_cstr); + a[0] = CORBA::string_dup (elem0_cstr); + a[1] = CORBA::string_dup (elem1_cstr); + a[2] = CORBA::string_dup (elem2_cstr); + a[3] = CORBA::string_dup (elem3_cstr); + + // test iterator copy constructor + ITERATOR_T a_it (a.begin ()); + FAIL_RETURN_IF (a_it != a.begin ()); + + // test assignment operator + a_it = a.begin (); + + // Create a case to test for memory leaks + // in the iterator. + *a_it = CORBA::string_dup (elem0_cstr); + FAIL_RETURN_IF (a_it != a.begin ()); + + // test non const dereferencing + // I'm not sure this test makes sense since what's returned from + // dereferencing the iterator is an r value. + const char* value_seq = a[0]; + FAIL_RETURN_IF (ACE_OS::strcmp (value_seq, elem0_cstr) != 0); + const char* value0 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem0_cstr) != 0); + + // test const dereferencing + const char* const value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem0_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem1_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.begin () < a_it)); + FAIL_RETURN_IF (a_it < a.begin ()); + + // test difference type + int a_diff = a_it - a.begin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.end (); + a_it--; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test pre-decrement operator + a_it = a.end (); + --a_it; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.begin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[0]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[2]) != 0); + + // test operator[] write + // NOTE: This assignment actually modifies the third element + // in the sequence since the iterator was previously positioned + // at the third element. I believe these are the proper semantics + // for using the bracket operator with an iterator. The number + // in the brackets is additive - not absolute. + a_it[0] = CORBA::string_dup (elem2_cstr); + FAIL_RETURN_IF (ACE_OS::strcmp (a[2], elem2_cstr) != 0); + + // reset content of sequence a + a[1] = CORBA::string_dup (elem1_cstr); + + // test for loop behaviour + ::CORBA::StringSeq b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + ITERATOR_T copytest_iter = test.begin (); + for (ITERATOR_T copya_iter = a.begin (); + copya_iter != a.end (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + std::ostream_iterator<CORBA::StringSeq::const_value_type> (ostream, + "\n")); + + // The third sequence element has been modified. Either we need to restore + // the original sequence values or modify the test here. I modified the + // test since it's easier. + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template <typename ITERATOR_T> +int test_sequence_const_iterator () +{ + ::CORBA::StringSeq a; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test for correct behaviour for empty sequence + + FAIL_RETURN_IF (a.begin() != a.end ()); + + // setup of an example sequence + + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + a.length (4); + a[0] = CORBA::string_dup (elem0_cstr); + a[0] = CORBA::string_dup (elem0_cstr); + a[1] = CORBA::string_dup (elem1_cstr); + a[2] = CORBA::string_dup (elem2_cstr); + a[3] = CORBA::string_dup (elem3_cstr); + + // test iterator copy constructor + ITERATOR_T a_it (a.begin ()); + FAIL_RETURN_IF (a_it != a.begin ()); + + // test assignment operator + a_it = a.begin (); + FAIL_RETURN_IF (a_it != a.begin ()); + + // test non const dereferencing + // I'm not sure non-const deferencing makes sense since + // we are getting an r value. + const char * value0 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem0_cstr) != 0); + + // test const dereferencing + const char* const value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem0_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem1_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.begin () < a_it)); + FAIL_RETURN_IF (a_it < a.begin ()); + + // test difference type + int a_diff = a_it - a.begin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.end (); + a_it--; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test pre-decrement operator + a_it = a.end (); + --a_it; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.begin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[0]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[2]) != 0); + + // test for loop behaviour + ::CORBA::StringSeq b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + ITERATOR_T copytest_iter = test.begin (); + for (ITERATOR_T copya_iter = a.begin (); + copya_iter != a.end (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + std::ostream_iterator<CORBA::StringSeq::const_value_type>(ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template <typename ITERATOR_T> +int test_const_sequence () +{ + // setup of an example sequence + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + ::CORBA::StringSeq setup; + setup.length (4); + setup[0] = CORBA::string_dup (elem0_cstr); + setup[1] = CORBA::string_dup (elem1_cstr); + setup[2] = CORBA::string_dup (elem2_cstr); + setup[3] = CORBA::string_dup (elem3_cstr); + + const ::CORBA::StringSeq a = setup; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + ITERATOR_T c_iter1 (a.begin ()); + ITERATOR_T c_iter2 = a.begin (); + FAIL_RETURN_IF (!(c_iter1 == c_iter2)); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test iterator copy constructor + ITERATOR_T a_it (a.begin ()); + FAIL_RETURN_IF (a_it != a.begin ()); + + // test non const dereferencing + // JWH2 - This test shouldn't be done when dealing with + // a const iterator (which we sometimes do with the current + // testing setup). + //typename ITERATOR_T::element_type value0 = *a_it; + //FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem0_cstr) != 0); + + // test const dereferencing + typename ITERATOR_T::const_element_type value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem0_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem1_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.begin () < a_it)); + FAIL_RETURN_IF (a_it < a.begin ()); + + // test difference type + int a_diff = a_it - a.begin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.end (); + a_it--; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test pre-decrement operator + a_it = a.end (); + --a_it; + FAIL_RETURN_IF (a_it == a.end ()); + FAIL_RETURN_IF ((a.end () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem3_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.begin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[0]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[2]) != 0); + + // test for loop behaviour + const ::CORBA::StringSeq b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + ITERATOR_T copytest_iter = test.begin (); + for (ITERATOR_T copya_iter = a.begin (); + copya_iter != a.end (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + std::ostream_iterator<CORBA::StringSeq::const_value_type> (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template <typename REVERSE_ITERATOR_T> +int test_sequence_reverse () +{ + ::CORBA::StringSeq a; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test for correct behaviour for empty sequence + + FAIL_RETURN_IF (a.begin() != a.end ()); + + // setup of an example sequence + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + a.length (4); + a[0] = CORBA::string_dup (elem0_cstr); + a[1] = CORBA::string_dup (elem1_cstr); + a[2] = CORBA::string_dup (elem2_cstr); + a[3] = CORBA::string_dup (elem3_cstr); + + // test iterator copy constructor + REVERSE_ITERATOR_T a_it (a.rbegin ()); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test assignment operator + a_it = a.rbegin (); + + // Create a case to test for memory leaks + // in the iterator. + *a_it = CORBA::string_dup (elem3_cstr); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + typename REVERSE_ITERATOR_T::element_type value0 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem3_cstr) != 0); + + // test const dereferencing + const char* const value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem3_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem2_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.rbegin () < a_it)); + FAIL_RETURN_IF (a_it < a.rbegin ()); + + // test difference type + int a_diff = a_it - a.rbegin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + REVERSE_ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + REVERSE_ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.rend (); + a_it--; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test pre-decrement operator + a_it = a.rend (); + --a_it; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.rbegin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[3]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[1]) != 0); + + // test operator[] write + a_it[0] = CORBA::string_dup (elem0_cstr); + FAIL_RETURN_IF (ACE_OS::strcmp (a[1],elem0_cstr) != 0); + + // reset content of sequence a + a[1] = CORBA::string_dup (elem1_cstr); + + // test for loop behaviour + ::CORBA::StringSeq b = a; + REVERSE_ITERATOR_T b_it = b.rbegin (); + + for (a_it = a.rbegin (); + a_it != a.rend (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + REVERSE_ITERATOR_T copytest_iter = test.rbegin (); + for (REVERSE_ITERATOR_T copya_iter = a.rbegin (); + copya_iter != a.rend (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + std::ostream_iterator<CORBA::StringSeq::element_type> (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template <typename REVERSE_ITERATOR_T> +int test_sequence_reverse_const_iterator () +{ + ::CORBA::StringSeq a; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test for correct behaviour for empty sequence + + FAIL_RETURN_IF (a.begin() != a.end ()); + + // setup of an example sequence + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + a.length (4); + a[0] = CORBA::string_dup (elem0_cstr); + a[1] = CORBA::string_dup (elem1_cstr); + a[2] = CORBA::string_dup (elem2_cstr); + a[3] = CORBA::string_dup (elem3_cstr); + + // test iterator copy constructor + REVERSE_ITERATOR_T a_it (a.rbegin ()); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test assignment operator + a_it = a.rbegin (); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + typename REVERSE_ITERATOR_T::const_element_type value0 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem3_cstr) != 0); + + // test const dereferencing + const char* const value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem3_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem2_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.rbegin () < a_it)); + FAIL_RETURN_IF (a_it < a.rbegin ()); + + // test difference type + int a_diff = a_it - a.rbegin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + REVERSE_ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + REVERSE_ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.rend (); + a_it--; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test pre-decrement operator + a_it = a.rend (); + --a_it; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.rbegin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[3]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[1]) != 0); + + // test for loop behaviour + ::CORBA::StringSeq b = a; + REVERSE_ITERATOR_T b_it = b.rbegin (); + + for (a_it = a.rbegin (); + a_it != a.rend (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + REVERSE_ITERATOR_T copytest_iter = test.rbegin (); + for (REVERSE_ITERATOR_T copya_iter = a.rbegin (); + copya_iter != a.rend (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + std::ostream_iterator<CORBA::StringSeq::element_type> (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template <typename REVERSE_ITERATOR_T> +int test_const_sequence_reverse () +{ + // setup of an example sequence + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + ::CORBA::StringSeq setup;; + setup.length (4); + setup[0] = CORBA::string_dup (elem0_cstr); + setup[1] = CORBA::string_dup (elem1_cstr); + setup[2] = CORBA::string_dup (elem2_cstr); + setup[3] = CORBA::string_dup (elem3_cstr); + + const ::CORBA::StringSeq a = setup; + + // test equality operator + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + + // test non-equality operator + FAIL_RETURN_IF (a.end () != a.end ()); + + // test iterator copy constructor + REVERSE_ITERATOR_T a_it (a.rbegin ()); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + typename REVERSE_ITERATOR_T::const_element_type value0 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value0, elem3_cstr) != 0); + + // test const dereferencing + const char* const value1 = *a_it; + FAIL_RETURN_IF (ACE_OS::strcmp (value1, elem3_cstr) != 0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem2_cstr) != 0); + + // test < operator + FAIL_RETURN_IF (!(a.rbegin () < a_it)); + FAIL_RETURN_IF (a_it < a.rbegin ()); + + // test difference type + int a_diff = a_it - a.rbegin (); + FAIL_RETURN_IF (a_diff != 1); + + // test copy constructor + REVERSE_ITERATOR_T a_it1 (a_it); + FAIL_RETURN_IF (a_it1 != a_it); + + // test preincrement operator + ++a_it1; + FAIL_RETURN_IF ((a_it1 - a_it) != 1); + + // test = and += operator + REVERSE_ITERATOR_T a_it2 = a_it += 3; + FAIL_RETURN_IF (a_it2 != a_it); + FAIL_RETURN_IF ((a_it - a_it1) != 2); + + // test + operator + a_it2 = a_it1 + 3; + FAIL_RETURN_IF ((a_it2 - a_it1) != 3); + + // test post-decrement operation + a_it = a.rend (); + a_it--; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test pre-decrement operator + a_it = a.rend (); + --a_it; + FAIL_RETURN_IF (a_it == a.rend ()); + FAIL_RETURN_IF ((a.rend () - a_it) != 1); + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, elem0_cstr) != 0); + + // test -= operator + a_it -= 3; + FAIL_RETURN_IF ((a_it1 - a_it) != 2); + + // test - operator + a_it2 = a_it1 - 2; + FAIL_RETURN_IF ((a_it1 - a_it2) != 2); + + // test operator[] read + a_it = a.rbegin (); + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[3]) != 0); + a_it += 2; + FAIL_RETURN_IF (ACE_OS::strcmp (a_it[0],a[1]) != 0); + + // test for loop behaviour + ::CORBA::StringSeq b = a; + REVERSE_ITERATOR_T b_it = b.rbegin (); + + for (a_it = a.rbegin (); + a_it != a.rend (); + a_it++, b_it++) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*a_it, *b_it) != 0); + } + + ::CORBA::StringSeq test; + test.length (a.length ()); + + std::copy (a.begin (), + a.end (), + test.begin ()); + + FAIL_RETURN_IF (test.length () != a.length ()); + + REVERSE_ITERATOR_T copytest_iter = test.rbegin (); + for (REVERSE_ITERATOR_T copya_iter = a.rbegin (); + copya_iter != a.rend (); + ++copya_iter, ++copytest_iter) + { + FAIL_RETURN_IF (ACE_OS::strcmp (*copya_iter, *copytest_iter) != 0); + } + + /// Testing - using ostream_iterator + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + std::ostream_iterator<CORBA::StringSeq::const_element_type> (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +#endif + +//----------------------------------------------------------------------------- + +int ACE_TMAIN(int,ACE_TCHAR*[]) +{ + int status = 0; + +#if defined TAO_HAS_SEQUENCE_ITERATORS && TAO_HAS_SEQUENCE_ITERATORS == 1 + + // Test Generic_Sequence_Iterator. + status += test_sequence< ::CORBA::StringSeq::iterator> (); + + // g++ seems to make the conversion from iterator to const_iterator + // and Windows doesn't. Not sure why. + // Test Const_Generic_Sequence_Iterator with non-const sequence. + status += test_sequence_const_iterator < + ::CORBA::StringSeq::const_iterator> (); + + // Test Const_Generic_Sequence_Iterator with const sequence. + status += test_const_sequence< ::CORBA::StringSeq::const_iterator> (); + + // Test Generic_Sequence_Reverse_Iterator. + status += test_sequence_reverse< ::CORBA::StringSeq::reverse_iterator> (); + + // Test Const_Generic_Sequence_Reverse_Iterator with non-const sequence. + status += test_sequence_reverse_const_iterator< + ::CORBA::StringSeq::const_reverse_iterator> (); + + // Test Const_Generic_Sequence_Reverse_Iterator with const sequence. + status += test_const_sequence_reverse< + ::CORBA::StringSeq::const_reverse_iterator> (); +#endif + + return status; +} |