From a6a06c78a7560f8a41b07316121e3589ea138b6e Mon Sep 17 00:00:00 2001 From: jhoffert Date: Fri, 20 Mar 2009 21:38:16 +0000 Subject: --- TAO/tests/Sequence_Iterators/Bounded_String.cpp | 703 +++++++++++++++ .../Sequence_Iterators/Sequence_Iterators.mpc | 39 + TAO/tests/Sequence_Iterators/StringSeq.cpp | 974 +++++++++++++++++++++ .../Sequence_Iterators/Unbounded_Objectref.cpp | 672 ++++++++++++++ TAO/tests/Sequence_Iterators/Unbounded_Value.cpp | 687 +++++++++++++++ TAO/tests/Sequence_Iterators/mock_reference.cpp | 90 ++ TAO/tests/Sequence_Iterators/mock_reference.hpp | 102 +++ TAO/tests/Sequence_Iterators/run_test.pl | 68 ++ TAO/tests/Sequence_Iterators/testing_counters.hpp | 106 +++ TAO/tests/Sequence_Iterators/testing_exception.hpp | 15 + 10 files changed, 3456 insertions(+) create mode 100644 TAO/tests/Sequence_Iterators/Bounded_String.cpp create mode 100644 TAO/tests/Sequence_Iterators/Sequence_Iterators.mpc create mode 100644 TAO/tests/Sequence_Iterators/StringSeq.cpp create mode 100644 TAO/tests/Sequence_Iterators/Unbounded_Objectref.cpp create mode 100644 TAO/tests/Sequence_Iterators/Unbounded_Value.cpp create mode 100644 TAO/tests/Sequence_Iterators/mock_reference.cpp create mode 100644 TAO/tests/Sequence_Iterators/mock_reference.hpp create mode 100755 TAO/tests/Sequence_Iterators/run_test.pl create mode 100644 TAO/tests/Sequence_Iterators/testing_counters.hpp create mode 100644 TAO/tests/Sequence_Iterators/testing_exception.hpp diff --git a/TAO/tests/Sequence_Iterators/Bounded_String.cpp b/TAO/tests/Sequence_Iterators/Bounded_String.cpp new file mode 100644 index 00000000000..f8556f7ae43 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/Bounded_String.cpp @@ -0,0 +1,703 @@ +/** + * @file Unbounded_String.cpp + * + * @brief test for STL iterator behaviour of CORBA bounded string sequence + * + * $Id$ + * + * @author Friedhelm Wolf (fwolf@dre.vanderbilt.edu) + */ + +#include +#include +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" + +#include +#include +#include + +typedef TAO::bounded_basic_string_sequence s_sequence; + +#define FAIL_RETURN_IF(CONDITION) \ + if (CONDITION) \ + { \ + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \ + return 1; \ + } + +template +int test_sequence () +{ + s_sequence 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 + a.length (4); + + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //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 now changes the sequence a. + // NOTE: This does not work for const_iterators + // a_it[0] = CORBA::string_dup (elem0_cstr); + // FAIL_RETURN_IF (ACE_OS::strcmp (a[2],elem0_cstr) != 0); + + // reset content of sequence a + //a[2] = CORBA::string_dup (elem2_cstr); + + // test for loop behaviour + s_sequence 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); + } + + s_sequence test; + test.length (4); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence () +{ + // setup of an example sequence + s_sequence setup; + setup.length (4); + + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + 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 s_sequence 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 + 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //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 now changes the sequence a. + // NOTE: This does not work for const_iterators + // a_it[0] = CORBA::string_dup (elem0_cstr); + // FAIL_RETURN_IF (ACE_OS::strcmp (a[2],elem0_cstr) != 0); + + // reset content of sequence a + //a[2] = CORBA::string_dup (elem2_cstr); + + // test for loop behaviour + s_sequence 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); + } + + s_sequence test; + test.length (4); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_sequence_reverse () +{ + s_sequence 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 + a.length (4); + + 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //char* 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 + // NOTE: This now changes the sequence a. + // this is not possible for const iterators + // 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 + s_sequence 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); + } + + s_sequence test; + test.length (a.length ()); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence_reverse () +{ + // setup of an example sequence + s_sequence setup; + setup.length (4); + + const char * elem0_cstr = "elem0"; + const char * elem1_cstr = "elem1"; + const char * elem2_cstr = "elem2"; + const char * elem3_cstr = "elem3"; + + 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 s_sequence 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 assignment operator + a_it = a.rbegin (); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //char* 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 + // NOTE: This now changes the sequence a. + // this is not possible for const iterators + // 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 + s_sequence 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); + } + + s_sequence test; + test.length (a.length ()); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +int main(int,char*[]) +{ + int status = 0; + + // Test Generic_Sequence_Iterator. + status += test_sequence (); + +#ifndef WIN32 + // 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 (); +#endif + + // Test Const_Generic_Sequence_Iterator with const sequence. + status += test_const_sequence (); + + // Test Generic_Sequence_Reverse_Iterator. + status += test_sequence_reverse (); + + // Test Const_Generic_Sequence_Reverse_Iterator with non-const sequence. + status += test_sequence_reverse (); + + // Test Const_Generic_Sequence_Reverse_Iterator with const sequence. + status += test_const_sequence_reverse (); + + return status; +} \ No newline at end of file diff --git a/TAO/tests/Sequence_Iterators/Sequence_Iterators.mpc b/TAO/tests/Sequence_Iterators/Sequence_Iterators.mpc new file mode 100644 index 00000000000..e590fb0f526 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/Sequence_Iterators.mpc @@ -0,0 +1,39 @@ +// -*- MPC -*- +// $Id$ + +project(StringSeq) : taoexe { + + exename = StringSeq + + Source_Files { + StringSeq.cpp + } +} + +project(Bounded_String) : taoexe { + + exename = Bounded_String + + Source_Files { + Bounded_String.cpp + } +} + +project(Unbounded_Value) : taoexe { + + exename = Unbounded_Value + + Source_Files { + Unbounded_Value.cpp + } +} + +project(Unbounded_Objectref) : taoexe { + + exename = Unbounded_Objectref + + Source_Files { + mock_reference.cpp + Unbounded_Objectref.cpp + } +} \ No newline at end of file diff --git a/TAO/tests/Sequence_Iterators/StringSeq.cpp b/TAO/tests/Sequence_Iterators/StringSeq.cpp new file mode 100644 index 00000000000..63c88554da3 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/StringSeq.cpp @@ -0,0 +1,974 @@ +/** + * @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 +#include +#include + +#define FAIL_RETURN_IF(CONDITION) \ + if (CONDITION) \ + { \ + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \ + return 1; \ + } + +//----------------------------------------------------------------------------- + +template +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 (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 +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 ()); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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(ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +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 + // JWH2 - Below are (failed) attempts to make the compiler happy. + // The compiler wants to construct a UBS_Sequence_Iterator and + // complains about the constructor being passed a const sequence + // pointer when it expects a non-const pointer. Why is the compiler + // trying to construct a UBS_Sequence_Iterator rather than a + // Const_UBS_Sequence_Iterator?? + // + FAIL_RETURN_IF (!(a.begin () == a.begin ())); + //ITERATOR_T c_iter1 (a.begin ()); + //::CORBA::StringSeq::const_iterator c_iter1 (a.begin ()); + //::TAO::Const_UBS_Sequence_Iterator > 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 - I guess this test shouldn't be done since we are dealing with + // a const iterator. Is that right? + //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 (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +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 (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +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 (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +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 (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +int main(int,char*[]) +{ + int status = 0; + + // Test Generic_Sequence_Iterator. + status += test_sequence< ::CORBA::StringSeq::iterator> (); + +#ifndef WIN32 + // 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> (); +#endif + + // 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> (); + + return status; +} diff --git a/TAO/tests/Sequence_Iterators/Unbounded_Objectref.cpp b/TAO/tests/Sequence_Iterators/Unbounded_Objectref.cpp new file mode 100644 index 00000000000..fa8fdb4d8e0 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/Unbounded_Objectref.cpp @@ -0,0 +1,672 @@ +/** + * @file Unbounded_Objectref.cpp + * + * @brief test for STL iterator behaviour of CORBA unbounded object reference + * sequence + * + * $Id$ + * + * @author Friedhelm Wolf (fwolf@dre.vanderbilt.edu) + */ + +#include "ace/Log_Msg.h" + +#include +#include +#include + +#include "tao/Object_Reference_Traits_T.h" +#include "mock_reference.hpp" +#include "tao/Unbounded_Object_Reference_Sequence_T.h" + +#define FAIL_RETURN_IF(CONDITION) \ + if (CONDITION) \ + { \ + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \ + return 1; \ + } + +typedef TAO::unbounded_object_reference_sequence tested_sequence; + +template +int test_sequence () +{ + tested_sequence 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 ()); + + mock_reference* elem0 = mock_reference::allocate (0); + mock_reference* elem1 = mock_reference::allocate (1); + mock_reference* elem2 = mock_reference::allocate (2); + mock_reference* elem3 = mock_reference::allocate (3); + + // setup of an example sequence + a.length (4); + + a[0] = elem0; + a[1] = elem1; + a[2] = elem2; + a[3] = elem3; + + // 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 + mock_reference* value0 = *a_it; + FAIL_RETURN_IF (value0->id () != elem0->id ()); + + // test const dereferencing + const mock_reference* const value1 = *a_it; + FAIL_RETURN_IF (value1->id () != elem0->id ()); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF ((*a_it)->id () != elem1->id ()); + + // 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 ((*a_it)->id () != elem3->id ()); + + // 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 ((*a_it)->id () != elem3->id ()); + + // 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 (a_it[0]->id () != a[0]->id ()); + a_it += 2; + FAIL_RETURN_IF (a_it[0]->id () != a[2]->id ()); + + // test for loop behaviour + tested_sequence b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF ((*a_it)->id () != (*b_it)->id ()); + } + + tested_sequence test; + test.length (a.length ()); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 ((*copya_iter)->id () != (*copytest_iter)->id ()); + } + + /// Testing - using ostream_iterator + /// JWH2 - I don't think the ostream test makes sense for object references. + /* + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + */ + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence () +{ + // setup of an example sequence + tested_sequence setup; + setup.length (4); + + mock_reference* elem0 = mock_reference::allocate (0); + mock_reference* elem1 = mock_reference::allocate (1); + mock_reference* elem2 = mock_reference::allocate (2); + mock_reference* elem3 = mock_reference::allocate (3); + + // setup of an example sequence + setup[0] = elem0; + setup[1] = elem1; + setup[2] = elem2; + setup[3] = elem3; + + const tested_sequence 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 + 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 + mock_reference* value0 = *a_it; + FAIL_RETURN_IF (value0->id () != elem0->id ()); + + // test const dereferencing + const mock_reference* const value1 = *a_it; + FAIL_RETURN_IF (value1->id () != elem0->id ()); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF ((*a_it)->id () != elem1->id ()); + + // 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 ((*a_it)->id () != elem3->id ()); + + // 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 ((*a_it)->id () != elem3->id ()); + + // 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 ((a_it[0])->id () != a[0]->id ()); + a_it += 2; + FAIL_RETURN_IF ((a_it[0])->id () != a[2]->id ()); + + // test for loop behaviour + tested_sequence b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF ((*a_it)->id () != (*b_it)->id ()); + } + + tested_sequence test; + test.length (4); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + /* + * The copy call below causes double deletes and seg faults. + 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 ((*copya_iter)->id () != (*copytest_iter)->id ()); + } + */ + + /// Testing - using ostream_iterator + /// JWH2 - I don't think the ostream test makes sense for object references. + /* + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem0\nelem1\nelem2\nelem3\n") != 0); + */ + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_sequence_reverse () +{ + tested_sequence 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 + a.length (4); + + mock_reference* elem0 = mock_reference::allocate (0); + mock_reference* elem1 = mock_reference::allocate (1); + mock_reference* elem2 = mock_reference::allocate (2); + mock_reference* elem3 = mock_reference::allocate (3); + + // setup of an example sequence + a.length (4); + a[0] = elem0; + a[1] = elem1; + a[2] = elem2; + a[3] = elem3; + + // 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 + mock_reference* value0 = *a_it; + FAIL_RETURN_IF (value0->id () != elem3->id ()); + + // test const dereferencing + const mock_reference* const value1 = *a_it; + FAIL_RETURN_IF (value1->id () != elem3->id ()); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF ((*a_it)->id () != elem2->id ()); + + // 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 ((*a_it)->id () != elem0->id ()); + + // 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 ((*a_it)->id () != elem0->id ()); + + // 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 ((a_it[0])->id () != a[3]->id ()); + a_it += 2; + FAIL_RETURN_IF ((a_it[0])->id () != a[1]->id ()); + + // test for loop behaviour + tested_sequence 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 ((*a_it)->id () != (*b_it)->id ()); + } + + tested_sequence test; + test.length (a.length ()); + + // Memory is leaked here from + // TAO::details::string_traits_base::default_initializer() + + 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 ((*copya_iter)->id () != (*copytest_iter)->id ()); + } + + /// Testing - using ostream_iterator + /// JWH2 - I don't think the ostream test makes sense for object references. + /* + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + */ + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence_reverse () +{ + // setup of an example sequence + tested_sequence setup; + setup.length (4); + + mock_reference* elem0 = mock_reference::allocate (0); + mock_reference* elem1 = mock_reference::allocate (1); + mock_reference* elem2 = mock_reference::allocate (2); + mock_reference* elem3 = mock_reference::allocate (3); + + // setup of an example sequence + setup[0] = elem0; + setup[1] = elem1; + setup[2] = elem2; + setup[3] = elem3; + + const tested_sequence 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 assignment operator + a_it = a.rbegin (); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + mock_reference* value0 = *a_it; + FAIL_RETURN_IF (value0->id () != elem3->id ()); + + // test const dereferencing + const mock_reference* const value1 = *a_it; + FAIL_RETURN_IF (value1->id () != elem3->id ()); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF ((*a_it)->id () != elem2->id ()); + + // 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 ((*a_it)->id () != elem0->id ()); + + // 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 ((*a_it)->id () != elem0->id ()); + + // 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 ((a_it[0])->id () != a[3]->id ()); + a_it += 2; + FAIL_RETURN_IF ((a_it[0])->id () != a[1]->id ()); + + // test operator[] write + // NOTE: This now changes the sequence a. + // this is not possible for const iterators + // 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 + tested_sequence 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 ((*a_it)->id () != (*b_it)->id ()); + } + + tested_sequence test; + test.length (a.length ()); + + /* + * The copy call below causes double deletes and seg faults. + 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 ((*copya_iter)->id () != (*copytest_iter)->id ()); + } + */ + + /// Testing - using ostream_iterator + /// JWH2 - I don't think the ostream test makes sense for object references. + /* + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("elem3\nelem2\nelem1\nelem0\n") != 0); + */ + + return 0; +} + +//----------------------------------------------------------------------------- + +int main(int,char*[]) +{ + int status = 0; + + // Test Generic_Sequence_Iterator. + status += test_sequence< tested_sequence::iterator> (); + +#ifndef WIN32 + // 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< tested_sequence::const_iterator> (); +#endif + + // Test Const_Generic_Sequence_Iterator with const sequence. + status += test_const_sequence< tested_sequence::const_iterator> (); + + // Test Generic_Sequence_Reverse_Iterator. + status += test_sequence_reverse< tested_sequence::reverse_iterator> (); + + // Test Const_Generic_Sequence_Reverse_Iterator with non-const sequence. + status += test_sequence_reverse< tested_sequence::const_reverse_iterator> (); + + // Test Const_Generic_Sequence_Reverse_Iterator with const sequence. + status += test_const_sequence_reverse< tested_sequence::const_reverse_iterator> (); + + return status; +} diff --git a/TAO/tests/Sequence_Iterators/Unbounded_Value.cpp b/TAO/tests/Sequence_Iterators/Unbounded_Value.cpp new file mode 100644 index 00000000000..0aabf9b81d2 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/Unbounded_Value.cpp @@ -0,0 +1,687 @@ +/** + * @file Unbounded_String.cpp + * + * @brief test for STL iterator behaviour of CORBA bounded string sequence + * + * $Id$ + * + * @author Friedhelm Wolf (fwolf@dre.vanderbilt.edu) + */ + +#include +#include "ace/Log_Msg.h" + +#include +#include +#include + +typedef TAO::unbounded_value_sequence v_sequence; + +#define FAIL_RETURN_IF(CONDITION) \ + if (CONDITION) \ + { \ + ACE_DEBUG ((LM_ERROR, ACE_TEXT ("\tFailed at %N:%l\n"))); \ + return 1; \ + } + +template +int test_sequence () +{ + v_sequence 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 + a.length (4); + + int elem0 = 0; + int elem1 = 1; + int elem2 = 2; + int elem3 = 3; + + a[0] = elem0; + a[1] = elem1; + a[2] = elem2; + a[3] = elem3; + + // 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //int value0 = *a_it; + //FAIL_RETURN_IF (value0 != elem0); + + // test const dereferencing + int value1 = *a_it; + FAIL_RETURN_IF (value1 != elem0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF (*a_it != elem1); + + // 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 (*a_it != elem3); + + // 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 (*a_it != elem3); + + // 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 (a_it[0] != a[0]); + a_it += 2; + FAIL_RETURN_IF (a_it[0] != a[2]); + + // test operator[] write + // NOTE: This now changes the sequence a. + // NOTE: This does not work for const_iterators + // a_it[0] = elem0; + // FAIL_RETURN_IF (a[2] != elem0); + + // reset content of sequence a + //a[2] = elem2; + + // test for loop behaviour + v_sequence b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF (*a_it != *b_it); + } + + v_sequence test; + test.length (4); + + 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 (*copya_iter != *copytest_iter); + } + + /// Testing - using ostream_iterator + + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("0\n1\n2\n3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence () +{ + // setup of an example sequence + v_sequence setup; + setup.length (4); + + int elem0 = 0; + int elem1 = 1; + int elem2 = 2; + int elem3 = 3; + + setup[0] = elem0; + setup[1] = elem1; + setup[2] = elem2; + setup[3] = elem3; + + const v_sequence 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 + 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //char* value0 = *a_it; + //FAIL_RETURN_IF (value0 != elem0); + + // test const dereferencing + int value1 = *a_it; + FAIL_RETURN_IF (value1 != elem0); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.begin()); + FAIL_RETURN_IF (*a_it != elem1); + + // 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 (*a_it != elem3); + + // 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 (*a_it != elem3); + + // 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 (a_it[0] != a[0]); + a_it += 2; + FAIL_RETURN_IF (a_it[0] != a[2]); + + // test operator[] write + // NOTE: This now changes the sequence a. + // NOTE: This does not work for const_iterators + // a_it[0] = elem0; + // FAIL_RETURN_IF (a[2] != elem0); + + // reset content of sequence a + //a[2] = elem2; + + // test for loop behaviour + v_sequence b = a; + ITERATOR_T b_it = b.begin (); + + for (a_it = a.begin (); + a_it != a.end (); + a_it++, b_it++) + { + FAIL_RETURN_IF (*a_it != *b_it); + } + + v_sequence test; + test.length (4); + + 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 (*copya_iter != *copytest_iter); + } + + /// Testing - using ostream_iterator + + std::ostringstream ostream; + std::copy (a.begin (), + a.end (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("0\n1\n2\n3\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_sequence_reverse () +{ + v_sequence 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 + a.length (4); + + int elem0 = 0; + int elem1 = 1; + int elem2 = 2; + int elem3 = 3; + + a[0] = elem0; + a[1] = elem1; + a[2] = elem2; + a[3] = elem3; + + // 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 + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //int value0 = *a_it; + //FAIL_RETURN_IF (value0 != elem3); + + // test const dereferencing + int value1 = *a_it; + FAIL_RETURN_IF (value1 != elem3); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF (*a_it != elem2); + + // 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 (*a_it != elem0); + + // 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 (*a_it != elem0); + + // 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 (a_it[0] != a[3]); + a_it += 2; + FAIL_RETURN_IF (a_it[0] != a[1]); + + // test operator[] write + // NOTE: This now changes the sequence a. + // this is not possible for const iterators + // a_it[0] = elem0; + // FAIL_RETURN_IF (a[1] != elem0); + + // reset content of sequence a + //a[1] = elem1; + + // test for loop behaviour + v_sequence 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 (*a_it != *b_it); + } + + v_sequence 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 (*copya_iter != *copytest_iter); + } + + /// Testing - using ostream_iterator + + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("3\n2\n1\n0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +template +int test_const_sequence_reverse () +{ + // setup of an example sequence + v_sequence setup; + setup.length (4); + + int elem0 = 0; + int elem1 = 1; + int elem2 = 2; + int elem3 = 3; + + setup[0] = elem0; + setup[1] = elem1; + setup[2] = elem2; + setup[3] = elem3; + + const v_sequence 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 assignment operator + a_it = a.rbegin (); + FAIL_RETURN_IF (a_it != a.rbegin ()); + + // test non const dereferencing + // JWH2 - I don't think this test makes sense. I believe the compiler + // will always return a const value since the dereference is on + // the right hand side of the assignment (i.e., r value). + //int value0 = *a_it; + //FAIL_RETURN_IF (value0 != elem3); + + // test const dereferencing + int value1 = *a_it; + FAIL_RETURN_IF (value1 != elem3); + + // test increment operation + a_it++; + FAIL_RETURN_IF (a_it == a.rbegin()); + FAIL_RETURN_IF (*a_it != elem2); + + // 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 (*a_it != elem0); + + // 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 (*a_it != elem0); + + // 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 (a_it[0] != a[3]); + a_it += 2; + FAIL_RETURN_IF (a_it[0] != a[1]); + + // test operator[] write + // NOTE: This now changes the sequence a. + // this is not possible for const iterators + // a_it[0] = elem0; + // FAIL_RETURN_IF (a[1] != elem0); + + // reset content of sequence a + //a[1] = elem1; + + // test for loop behaviour + v_sequence 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 (*a_it != *b_it); + } + + v_sequence 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 (*copya_iter != *copytest_iter); + } + + /// Testing - using ostream_iterator + + std::ostringstream ostream; + std::copy (a.rbegin (), + a.rend (), + // JWH2 - I changed value_type to const_value_type. Is that + // the correct approach? + std::ostream_iterator (ostream, + "\n")); + + FAIL_RETURN_IF ( + ostream.str ().compare ("3\n2\n1\n0\n") != 0); + + return 0; +} + +//----------------------------------------------------------------------------- + +int main(int,char*[]) +{ + int status = 0; + + // Test Generic_Sequence_Iterator. + status += test_sequence (); + +#ifndef WIN32 + // 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 (); +#endif + + // Test Const_Generic_Sequence_Iterator with const sequence. + status += test_const_sequence (); + + // Test Generic_Sequence_Reverse_Iterator. + status += test_sequence_reverse (); + + // Test Const_Generic_Sequence_Reverse_Iterator with non-const sequence. + status += test_sequence_reverse (); + + // Test Const_Generic_Sequence_Reverse_Iterator with const sequence. + status += test_const_sequence_reverse (); + + return status; +} diff --git a/TAO/tests/Sequence_Iterators/mock_reference.cpp b/TAO/tests/Sequence_Iterators/mock_reference.cpp new file mode 100644 index 00000000000..a1115c0f094 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/mock_reference.cpp @@ -0,0 +1,90 @@ +/** + * @file + * + * $Id$ + * + * @author Carlos O'Ryan + */ +#include "mock_reference.hpp" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +mock_reference:: +~mock_reference() +{ +} + +mock_reference * mock_reference:: +allocate(int id) +{ + return new mock_reference(id); +} + +mock_reference * mock_reference:: +_nil() +{ + return 0; +} + +mock_reference * mock_reference:: +_duplicate(mock_reference * rhs) +{ + if (rhs == 0) + { + return 0; + } + return new mock_reference(*rhs); +} + +void mock_reference:: +_tao_release(mock_reference * rhs) +{ + delete rhs; +} + +void CORBA::release(mock_reference * r) +{ + mock_reference::_tao_release(r); +} + +mock_reference * +TAO::Objref_Traits::duplicate ( + mock_reference_ptr p + ) +{ + return mock_reference::_duplicate (p); +} + +void +TAO::Objref_Traits::release ( + mock_reference_ptr p + ) +{ + CORBA::release (p); +} + +mock_reference_ptr +TAO::Objref_Traits::nil (void) +{ + return mock_reference::_nil (); +} + +CORBA::Boolean +TAO::Objref_Traits::marshal ( + const mock_reference_ptr, + TAO_OutputCDR & + ) +{ + return true; +} + +CORBA::Boolean operator<< (TAO_OutputCDR &, const mock_reference *) +{ + return true; +} +CORBA::Boolean operator>> (TAO_InputCDR &, mock_reference *&) +{ + return true; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tests/Sequence_Iterators/mock_reference.hpp b/TAO/tests/Sequence_Iterators/mock_reference.hpp new file mode 100644 index 00000000000..ecac1eb6eb1 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/mock_reference.hpp @@ -0,0 +1,102 @@ +#ifndef guard_mock_reference_hpp +#define guard_mock_reference_hpp +/** + * @file + * + * @brief Mock an object reference so we can test the sequences in + * isolation. + * + * $Id$ + * + * @author Carlos O'Ryan + */ +#include "ace/config-all.h" + +#include "tao/Basic_Types.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL +// Forward declare the class a CORBA::release function for it. That +// avoids having to introduce CORBA::Object into the tests. +// Ideally the T_var and T_out types should accept mock objects +// too, but that is too much to bite in the current iteration. +class mock_reference; +namespace CORBA +{ +void release(mock_reference*); +} + +class mock_stream; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include "tao/Objref_VarOut_T.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +typedef mock_reference *mock_reference_ptr; +typedef TAO_Objref_Var_T mock_reference_var; +typedef TAO_Objref_Out_T mock_reference_out; + +/** + * @class mock_reference + * + * @brief Implement a concrete class with the right interface for an + * object reference. + */ +class mock_reference +{ +public: + virtual ~mock_reference(); + + typedef mock_reference_var _var_type; + typedef mock_reference_out _out_type; + + static mock_reference * allocate(int id); + static mock_reference * _nil(); + + static mock_reference * _duplicate(mock_reference * rhs); + static void _tao_release(mock_reference * rhs); + + inline bool operator==(mock_reference const & rhs) const + { + return id_ == rhs.id_; + } + + inline bool operator!=(mock_reference const & rhs) const + { + return !(*this == rhs); + } + + inline int id() const + { + return id_; + } + +private: + mock_reference (); + + inline mock_reference(int id) + : id_(id) + {} + +private: + int id_; +}; + +CORBA::Boolean operator<< (TAO_OutputCDR &, const mock_reference *); +CORBA::Boolean operator>> (TAO_InputCDR &, mock_reference *&); + +namespace TAO +{ + template<> + struct Objref_Traits< mock_reference> + { + static mock_reference_ptr duplicate (mock_reference_ptr); + static void release (mock_reference_ptr); + static mock_reference_ptr nil (void); + static CORBA::Boolean marshal (const mock_reference_ptr p, TAO_OutputCDR & cdr); + }; +} + +TAO_END_VERSIONED_NAMESPACE_DECL +#endif // guard_mock_reference_hpp diff --git a/TAO/tests/Sequence_Iterators/run_test.pl b/TAO/tests/Sequence_Iterators/run_test.pl new file mode 100755 index 00000000000..e0c7ed6afcb --- /dev/null +++ b/TAO/tests/Sequence_Iterators/run_test.pl @@ -0,0 +1,68 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use strict; + +if ($ARGV[0] =~ /^-h/i || $ARGV[0] =~ /^-\?/i) { + print "Usage: run_test.pl [-boost|-noboost]\n". + "\tDefault is to run all tests, specifying -boost or -noboost will\n". + "\teither run the tests that require the boost unit test library or\n". + "\tthe other tests, respectively.\n"; + exit 0; +} + +my $final_result = 0; + +my @testsToRun = qw( + StringSeq + Bounded_String + Unbounded_Value + Unbounded_Objectref + ); + +foreach my $process (@testsToRun) { + + my $P = 0; + if (PerlACE::is_vxworks_test()) { + $P = new PerlACE::ProcessVX ($process, + '--log_level=nothing ' + .'--report_level=no'); + } + else { + $P = new PerlACE::Process ($process, + '--log_level=nothing ' + .'--report_level=no'); + } + my $executable = $P->Executable; + + # Not all the binaries are generated in all configurations. + if (PerlACE::is_vxworks_test()) { + next unless -e $executable; + } + else { + next unless -x $executable; + } + + print "Running $process ..."; + my $result = $P->Spawn; + if ($result != 0) { + print "FAILED\n"; + $final_result = 1; + next; + } + $result = $P->WaitKill($PerlACE::wait_interval_for_process_creation); + if ($result != 0) { + print "FAILED\n"; + $final_result = 1; + next; + } + print "SUCCESS\n"; +} + +exit $final_result; diff --git a/TAO/tests/Sequence_Iterators/testing_counters.hpp b/TAO/tests/Sequence_Iterators/testing_counters.hpp new file mode 100644 index 00000000000..e5f20bb8ee1 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/testing_counters.hpp @@ -0,0 +1,106 @@ +#ifndef guard_testing_counters_hpp +#define guard_testing_counters_hpp +/** + * @file + * + * @brief Some unit tests need to count how many times a function is + * called. Here we implement some simple helper classes for that + * purpose. + * + * $Id$ + * + * @author Carlos O'Ryan + */ + +#include "testing_exception.hpp" + +#include + +#include + +/** + * @brief Used to count how many times a function gets called. The + * unit test should create one instance per function. + */ +class call_counter +{ +public: + inline call_counter() + : count_(0) + , failure_countdown_(0) + {} + + inline long current_count() const + { + return count_; + } + + inline void failure_countdown(long countdown) + { + failure_countdown_ = countdown; + } + + inline void operator()() + { + ++count_; + if (--failure_countdown_ == 0) + { + throw testing_exception(); + } + } + +private: + long count_; + long failure_countdown_; +}; + +/** + * @brief Used to detect if a testing_counter is "called" the right + * number of times. + */ +class expected_calls + : private boost::noncopyable +{ +public: + inline expected_calls(call_counter const & counter) + : current_count_(counter.current_count()) + , previous_count_(counter.current_count()) + , counter_(counter) + { } + + inline bool expect(long n) + { + reset(); + return (previous_count_ + n == current_count_); + } + + inline void reset() + { + previous_count_ = current_count_; + current_count_ = counter_.current_count(); + } + + inline long current_count() const + { + return current_count_; + } + + inline long previous_count() const + { + return previous_count_; + } + +private: + long current_count_; + long previous_count_; + call_counter const & counter_; +}; + +inline std::ostream & operator<<(std::ostream & os, expected_calls const & x) +{ + return os << "current=" << x.current_count() + << ",previous=" << x.previous_count(); + +} + +#endif // guard_testing_counters_hpp diff --git a/TAO/tests/Sequence_Iterators/testing_exception.hpp b/TAO/tests/Sequence_Iterators/testing_exception.hpp new file mode 100644 index 00000000000..2fc4c540197 --- /dev/null +++ b/TAO/tests/Sequence_Iterators/testing_exception.hpp @@ -0,0 +1,15 @@ +#ifndef guard_testing_exception_hpp +#define guard_testing_exception_hpp +/** + * @file + * + * @brief Simple exception to raise in the tests. + * + * $Id$ + * + * @author Carlos O'Ryan + */ + +struct testing_exception {}; + +#endif // guard_testing_exception_hpp -- cgit v1.2.1