summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-09-22 00:32:03 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-09-22 00:32:03 +0000
commite25db3aefe4be43b8bf17d90aaeb4964f5ca1b54 (patch)
treea75e5a4723b59ef21731155ccddb53fbf72fbf83
parent1786c565d31b365d33f619efabc67247a920ce9f (diff)
downloadATCD-e25db3aefe4be43b8bf17d90aaeb4964f5ca1b54.tar.gz
Tue Sep 21 20:15:01 2004 Carlos O'Ryan <coryan@atdesk.com>
-rw-r--r--TAO/ChangeLog81
-rw-r--r--TAO/tests/Sequence_Unit_Tests/Bounded_Primitive_Types.cpp475
-rw-r--r--TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp10
-rw-r--r--TAO/tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc20
-rw-r--r--TAO/tests/Sequence_Unit_Tests/Unbounded_Primitive_Types.cpp520
-rw-r--r--TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp10
-rw-r--r--TAO/tests/Sequence_Unit_Tests/allocation_traits.hpp (renamed from TAO/tests/Sequence_Unit_Tests/sequence_traits.hpp)41
-rw-r--r--TAO/tests/Sequence_Unit_Tests/bounded_value_sequence.hpp91
-rw-r--r--TAO/tests/Sequence_Unit_Tests/bounded_value_sequence_ut.cpp320
-rw-r--r--TAO/tests/Sequence_Unit_Tests/generic_sequence.hpp41
-rw-r--r--TAO/tests/Sequence_Unit_Tests/range_checking.hpp53
-rwxr-xr-xTAO/tests/Sequence_Unit_Tests/run_test.pl4
-rw-r--r--TAO/tests/Sequence_Unit_Tests/sequence.hpp156
-rw-r--r--TAO/tests/Sequence_Unit_Tests/testing_allocation_traits.hpp91
-rw-r--r--TAO/tests/Sequence_Unit_Tests/testing_exception.hpp15
-rw-r--r--TAO/tests/Sequence_Unit_Tests/testing_range_checking.hpp57
-rw-r--r--TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence.hpp92
-rw-r--r--TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence_ut.cpp450
-rw-r--r--TAO/tests/Sequence_Unit_Tests/value_sequence_tester.hpp239
-rw-r--r--TAO/tests/Sequence_Unit_Tests/value_traits.hpp44
20 files changed, 1603 insertions, 1207 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 2240c447d23..463f88761d9 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,84 @@
+Tue Sep 21 20:15:01 2004 Carlos O'Ryan <coryan@atdesk.com>
+
+ * tests/Sequence_Unit_Tests/generic_sequence.hpp:
+ Refactor the code to decompose the problem a little better.
+ Basically it all boils down to creating
+
+ 1) A set of traits to handle buffer allocation. This
+ encapsulates the bounded vs. unbounded aspect of a sequence.
+
+ 2) Another set trait to handle element initialization,
+ copying and destruction. This encapsulates the value
+ vs. reference aspect of a sequence.
+
+ In the process I created smaller files to hold each class.
+ The traits have an extra <bool> template parameter, whose
+ motivation would hopefully become clear in a second.
+
+ * tests/Sequence_Unit_Tests/bounded_value_sequence.hpp:
+ Move the implementation of bounded sequences of by-value types
+ to this file.
+
+ * tests/Sequence_Unit_Tests/bounded_value_sequence_ut.cpp:
+ Unit test for bounded_value_sequence.
+
+ * tests/Sequence_Unit_Tests/unbounded_value_sequence.hpp:
+ Move the implementation of unbounded sequences of by-value types
+ to this file.
+
+ * tests/Sequence_Unit_Tests/unbounded_value_sequence_ut.cpp:
+ Unit test for unbounded_value_sequence.
+
+ * tests/Sequence_Unit_Tests/value_sequence_tester.hpp:
+ Refactor common code shared by bounded_value_sequence_ut.cpp and
+ unbounded_value_sequence_ut.cpp
+
+ * tests/Sequence_Unit_Tests/testing_allocation_traits.hpp:
+ Specialize the allocation traits in a form suitable for
+ testing. The unit tests make the traits raise exceptions in
+ certain tests, and they can count how many times certain
+ functions are called.
+
+ * tests/Sequence_Unit_Tests/testing_range_checking.hpp:
+ Specializes the range_checking traits to raise an exception when
+ an out-of-range access is attempted.
+
+ * tests/Sequence_Unit_Tests/testing_exception.hpp:
+ Exception raised by the testing traits.
+
+ * tests/Sequence_Unit_Tests/allocation_traits.hpp:
+ New file, implements the allocation traits for bounded and
+ unbounded sequences.
+
+ * tests/Sequence_Unit_Tests/value_traits.hpp:
+ Implement the element manipulation traits for by-value types.
+
+ * tests/Sequence_Unit_Tests/range_checking.hpp:
+ New file, implements yet another trait to control what are the
+ effects of accessing an index out of range. The default
+ implementation is a no-op, but applications can specialize the
+ class to throw exceptions, call abort, phone your mom and call
+ you names, whatever.
+
+ * tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc:
+ * tests/Sequence_Unit_Tests/run_test.pl:
+ Removed some projects, add new ones.
+
+ * tests/Sequence_Unit_Tests/Bounded_Primitive_Types.cpp:
+ * tests/Sequence_Unit_Tests/Unbounded_Primitive_Types.cpp:
+ Removed, replaced by {bounded,unbounded}_value_sequence_ut.cpp
+
+ * tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp:
+ * tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp:
+ Updated to use TAO::{bounded,unbounded}_value_sequence
+ vs. TAO::{bounded,unbounded}_sequence.
+
+ * tests/Sequence_Unit_Tests/sequence.hpp:
+ Removed, replaced by {bounded,unbounded}_value_sequence.hpp
+
+ * tests/Sequence_Unit_Tests/sequence_traits.hpp:
+ Removed, the traits have been broken up in multiple files.
+
Tue Sep 21 20:31:43 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu>
* orbsvcs/orbsvcs/Log/LogRecordStore_persist.cpp:
diff --git a/TAO/tests/Sequence_Unit_Tests/Bounded_Primitive_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Bounded_Primitive_Types.cpp
deleted file mode 100644
index 77948e18097..00000000000
--- a/TAO/tests/Sequence_Unit_Tests/Bounded_Primitive_Types.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/**
- * @file
- *
- * @brief Unit tests for bounded sequences, primitive-type case.
- *
- * Verify that bounded sequences of primitive types, self-managed
- * types work correctly. Such types include all the integer types,
- * the floating point types but do not include strings as those are
- * not self-managed. The fundamental difference with other
- * self-managed types, such as structures, is that the constructors
- * and assignment operators of primitive types cannot throw.
- *
- * $Id$
- *
- * @author Carlos O'Ryan
- */
-#define BOOST_AUTO_TEST_MAIN
-#include <boost/test/auto_unit_test.hpp>
-
-#include "sequence_traits.hpp"
-#include "generic_sequence.hpp"
-
-#include <sstream>
-#include <stdexcept>
-#include <iostream>
-
-struct local_exception {};
-
-CORBA::ULong const MAXIMUM = 32;
-
-namespace TAO
-{
-namespace details
-{
-
-template<>
-struct bounded_sequence_traits<int,MAXIMUM>
-{
- static long allocbuf_failure_counter;
- static long allocbuf_calls;
- static long freebuf_calls;
-
- typedef int value_type;
- inline static void check_index(
- CORBA::ULong index,
- CORBA::ULong length,
- CORBA::ULong maximum,
- char const * function_name)
- {
- if (index < length) {
- return;
- }
- std::ostringstream error;
- error << "Out of range access in " << function_name
- << ", index=" << index
- << ", length=" << length
- << ", maximum=" << maximum
- << ", class=bounded_sequence<int>";
- throw std::range_error(error.str());
- }
-
- inline static CORBA::ULong default_maximum()
- {
- return MAXIMUM;
- }
-
- inline static int * default_buffer_allocation()
- {
- return allocbuf(MAXIMUM);
- }
-
- inline static value_type * allocbuf(CORBA::ULong maximum)
- {
- ++allocbuf_calls;
- if (--allocbuf_failure_counter == 0)
- {
- throw local_exception();
- }
- if (maximum != MAXIMUM)
- {
- throw local_exception();
- }
- return new value_type[MAXIMUM];
- }
-
- inline static void freebuf(value_type * buffer)
- {
- ++freebuf_calls;
- delete[] buffer;
- }
-};
-
-} // namespace details
-} // namespace TAO
-
-#include "sequence.hpp"
-
-using namespace TAO;
-using namespace TAO::details;
-
-typedef bounded_sequence<int,MAXIMUM> tested_seq;
-typedef bounded_sequence_traits<int,MAXIMUM> test_traits;
-
-long test_traits::allocbuf_failure_counter = 0;
-long test_traits::allocbuf_calls = 0;
-long test_traits::freebuf_calls = 0;
-
-
-BOOST_AUTO_UNIT_TEST(test_allocations_in_constructors)
-{
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
-
- {
- tested_seq default_constructed;
- }
- BOOST_CHECK_EQUAL(++a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
-}
-
-void init(CORBA::ULong count, tested_seq & a)
-{
- a.length(count);
- for(CORBA::ULong i = 0; i != count; ++i) {
- a[i] = int(i);
- }
-}
-
-void check_init(CORBA::ULong count, tested_seq const & a)
-{
- BOOST_CHECK_EQUAL(CORBA::ULong(count), a.length());
- BOOST_CHECK_EQUAL(MAXIMUM, a.maximum());
- for(CORBA::ULong i = 0; i != count; ++i) {
- BOOST_CHECK_EQUAL(int(i), a[i]);
- }
-}
-
-void check_equal(
- tested_seq const & a,
- tested_seq const & b)
-{
- BOOST_CHECK_EQUAL(a.length(), b.length());
- BOOST_CHECK_EQUAL(a.maximum(), b.maximum());
- for(CORBA::ULong i = 0; i != a.length(); ++i) {
- BOOST_CHECK_EQUAL(a[i], b[i]);
- }
-}
-
-BOOST_AUTO_UNIT_TEST(test_default_constructor)
-{
- tested_seq default_constructed;
-
- BOOST_CHECK_EQUAL(CORBA::ULong(0), default_constructed.length());
- BOOST_CHECK_EQUAL(MAXIMUM, default_constructed.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_copy_constructor_from_default)
-{
- tested_seq default_constructed;
- tested_seq copy_constructed(default_constructed);
- BOOST_CHECK_EQUAL(CORBA::ULong(0), copy_constructed.length());
- BOOST_CHECK_EQUAL(MAXIMUM, copy_constructed.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_set_length)
-{
- tested_seq x;
-
- x.length(16);
- BOOST_CHECK_EQUAL(CORBA::ULong(16), x.length());
- BOOST_CHECK(CORBA::ULong(16) <= x.maximum());
-
- x.length(8);
- BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
- BOOST_CHECK(CORBA::ULong(8) <= x.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_setting_and_copy)
-{
- tested_seq a;
- init(16, a);
- check_init(16, a);
-
- tested_seq b(a);
- check_equal(a, b);
-}
-
-BOOST_AUTO_UNIT_TEST(test_setting_and_assign)
-{
- tested_seq a;
- init(16, a);
- check_init(16, a);
-
- tested_seq c;
- c = a;
- check_equal(a, c);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_default_constructor)
-{
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
-
- test_traits::allocbuf_failure_counter = 1;
- BOOST_CHECK_THROW(tested_seq dst, local_exception);
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_copy_constructor)
-{
- tested_seq src; src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
-
- test_traits::allocbuf_failure_counter = 1;
- BOOST_CHECK_THROW(tested_seq dst(src), local_exception);
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_assignment)
-{
- tested_seq src; src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- tested_seq dst; dst.length(8);
- dst[0] = 0; dst[6] = 5;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
-
- test_traits::allocbuf_failure_counter = 1;
- BOOST_CHECK_THROW(dst = src, local_exception);
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-
- BOOST_CHECK_EQUAL(8UL, dst.length());
- BOOST_CHECK_EQUAL(0, dst[0]);
- BOOST_CHECK_EQUAL(5, dst[6]);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_set_length)
-{
- tested_seq src; src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
-
- test_traits::allocbuf_failure_counter = 1;
- BOOST_CHECK_THROW(src.length(64), local_exception);
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-
- BOOST_CHECK_EQUAL(16UL, src.length());
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- BOOST_CHECK_EQUAL(int(i), src[i]);
-}
-
-BOOST_AUTO_UNIT_TEST(test_check_index_is_called)
-{
- tested_seq a;
- init(16, a);
-
- try
- {
- a[16] = 16;
- BOOST_ERROR("Missing range error exception");
- }
- catch(std::range_error const &) {}
- catch(...) {
- BOOST_ERROR("Unexpected exception raised");
- }
- check_init(16, a);
-}
-
-int * init_data()
-{
- int * data = tested_seq::allocbuf(MAXIMUM);
- data[0] = 1; data[1] = 4; data[2] = 9;
-
- return data;
-}
-
-void check_data(tested_seq const & a)
-{
- BOOST_CHECK_EQUAL(MAXIMUM, a.maximum());
- BOOST_CHECK_EQUAL(8UL, a.length());
- BOOST_CHECK_EQUAL(1, a[0]);
- BOOST_CHECK_EQUAL(4, a[1]);
- BOOST_CHECK_EQUAL(9, a[2]);
-}
-
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_default)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(8, data);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_false)
-{
- int * data = init_data();
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(8, data, false);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_true)
-{
- int * data = init_data();
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(8, data, true);
- check_data(a);
- BOOST_CHECK_EQUAL(true, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_default)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(8, data);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(++a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_false)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(8, data, false);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(++a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_true)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(8, data, true);
- check_data(a);
- BOOST_CHECK_EQUAL(true, a.release());
- }
- BOOST_CHECK_EQUAL(++a, test_traits::allocbuf_calls);
- ++f; ++f;
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_const)
-{
- int * data = init_data();
- tested_seq a(8, data, true);
- tested_seq const & b = a;
- BOOST_CHECK_EQUAL(b.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_default)
-{
- int * data = init_data();
- tested_seq a(8, data, true);
- BOOST_CHECK_EQUAL(a.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_false)
-{
- int * data = init_data();
- tested_seq a(8, data, true);
- BOOST_CHECK_EQUAL(a.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_true_with_release_false)
-{
- int * data = init_data();
- tested_seq a(8, data, false);
- BOOST_CHECK_EQUAL(static_cast<int*>(0), a.get_buffer(true));
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_true_with_release_true)
-{
- int * data = init_data();
- tested_seq a(8, data, true);
- BOOST_CHECK_EQUAL(data, a.get_buffer(true));
- tested_seq const & b = a;
- BOOST_CHECK_EQUAL(MAXIMUM, b.maximum());
- BOOST_CHECK_EQUAL(0UL, b.length());
- BOOST_CHECK(0 != b.get_buffer());
- BOOST_CHECK(data != b.get_buffer());
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_allocbuf_default)
-{
- int * data = tested_seq::allocbuf();
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_wrong_allocbuf_throws)
-{
- BOOST_CHECK_THROW(tested_seq::allocbuf(64), local_exception);
- BOOST_CHECK_THROW(tested_seq::allocbuf(16), local_exception);
-}
-
-#if !defined(BOOST_AUTO_TEST_MAIN)
-// This is just to convince MPC that I do not need a main() to have a
-// program.
-int main() {}
-#endif
diff --git a/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp
index 0365a9b57c3..e7ee0b86dc7 100644
--- a/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp
+++ b/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp
@@ -8,7 +8,7 @@
*
* @author Carlos O'Ryan
*/
-#include "sequence.hpp"
+#include "bounded_value_sequence.hpp"
struct Foo
{
@@ -20,14 +20,14 @@ CORBA::ULong const TEST_FOO_MAX = 64;
int main(int,char*[])
{
- typedef TAO::bounded_sequence<int,TEST_INT_MAX> int_sequence;
+ typedef TAO::bounded_value_sequence<int,TEST_INT_MAX> int_sequence;
int_sequence a;
int_sequence b(a);
a = b;
- typedef TAO::bounded_sequence<Foo,TEST_FOO_MAX> Foo_sequence;
+ typedef TAO::bounded_value_sequence<Foo,TEST_FOO_MAX> Foo_sequence;
Foo_sequence c;
Foo_sequence d(c);
@@ -40,5 +40,5 @@ int main(int,char*[])
// of all member function and thus tests the full class. This should
// work across all platforms, even on platforms that do not *require*
// explicit instantiation of templates.
-template class TAO::bounded_sequence<int,TEST_INT_MAX>;
-template class TAO::bounded_sequence<Foo,TEST_FOO_MAX>;
+template class TAO::bounded_value_sequence<int,TEST_INT_MAX>;
+template class TAO::bounded_value_sequence<Foo,TEST_FOO_MAX>;
diff --git a/TAO/tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc b/TAO/tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc
index 9d8561fec0f..d7e6504a9a1 100644
--- a/TAO/tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc
+++ b/TAO/tests/Sequence_Unit_Tests/Sequence_Unit_Tests.mpc
@@ -13,14 +13,26 @@ project(*Bounded_Simple_Types) : taoexe {
}
}
-project(*Unbounded_Primitive_Types): taoexe, boost_unit_test {
+// project(*Unbounded_String_Sequence): taoexe, boost_unit_test {
+// Source_Files {
+// unbounded_string_sequence_ut.cpp
+// }
+//}
+
+//project(*String_Sequence_Element): taoexe, boost_unit_test {
+// Source_Files {
+// string_sequence_element_ut.cpp
+// }
+//}
+
+project(*Unbounded_Value_Sequence): taoexe, boost_unit_test {
Source_Files {
- Unbounded_Primitive_Types.cpp
+ unbounded_value_sequence_ut.cpp
}
}
-project(*Bounded_Primitive_Types): taoexe, boost_unit_test {
+project(*Bounded_Value_Sequence): taoexe, boost_unit_test {
Source_Files {
- Bounded_Primitive_Types.cpp
+ bounded_value_sequence_ut.cpp
}
}
diff --git a/TAO/tests/Sequence_Unit_Tests/Unbounded_Primitive_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Unbounded_Primitive_Types.cpp
deleted file mode 100644
index 850b9416b73..00000000000
--- a/TAO/tests/Sequence_Unit_Tests/Unbounded_Primitive_Types.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/**
- * @file
- *
- * @brief Unit tests for bounded sequences, primitive-type case.
- *
- * Verify that bounded sequences of primitive types, self-managed
- * types work correctly. Such types include all the integer types,
- * the floating point types but do not include strings as those are
- * not self-managed. The fundamental difference with other
- * self-managed types, such as structures, is that the constructors
- * and assignment operators of primitive types cannot throw.
- *
- * $Id$
- *
- * @author Carlos O'Ryan
- */
-#define BOOST_AUTO_TEST_MAIN
-#include <boost/test/auto_unit_test.hpp>
-
-#include "sequence_traits.hpp"
-#include "generic_sequence.hpp"
-
-#include <sstream>
-#include <stdexcept>
-#include <iostream>
-
-struct local_exception {};
-
-namespace TAO
-{
-namespace details
-{
-
-template<>
-struct unbounded_sequence_traits<int>
-{
- static long allocbuf_failure_counter;
- static long allocbuf_calls;
- static long freebuf_calls;
-
- typedef int value_type;
- inline static void check_index(
- CORBA::ULong index,
- CORBA::ULong length,
- CORBA::ULong maximum,
- char const * function_name)
- {
- if (index < length) {
- return;
- }
- std::ostringstream error;
- error << "Out of range access in " << function_name
- << ", index=" << index
- << ", length=" << length
- << ", maximum=" << maximum
- << ", class=unbounded_sequence<int>";
- throw std::range_error(error.str());
- }
-
- inline static CORBA::ULong default_maximum()
- {
- return 0;
- }
-
- inline static int * default_buffer_allocation()
- {
- return 0;
- }
-
- inline static value_type * allocbuf(CORBA::ULong maximum)
- {
- ++allocbuf_calls;
- if (--allocbuf_failure_counter == 0)
- {
- throw local_exception();
- }
- return new value_type[maximum];
- }
-
- inline static void freebuf(value_type * buffer)
- {
- ++freebuf_calls;
- delete[] buffer;
- }
-};
-
-} // namespace details
-} // namespace TAO
-
-#include "sequence.hpp"
-
-using namespace TAO;
-using namespace TAO::details;
-
-typedef unbounded_sequence<int> tested_seq;
-typedef unbounded_sequence_traits<int> test_traits;
-
-long test_traits::allocbuf_failure_counter = 0;
-long test_traits::allocbuf_calls = 0;
-long test_traits::freebuf_calls = 0;
-
-
-BOOST_AUTO_UNIT_TEST(test_allocations_in_constructors)
-{
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
-
- {
- tested_seq default_constructed;
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
-
- {
- tested_seq maximum_constructed(16);
- }
- BOOST_CHECK_EQUAL(++a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
-}
-
-void init(CORBA::ULong count, tested_seq & a)
-{
- a.length(count);
- for(CORBA::ULong i = 0; i != count; ++i) {
- a[i] = int(i);
- }
-}
-
-void check_init(CORBA::ULong count, tested_seq const & a)
-{
- BOOST_CHECK_EQUAL(CORBA::ULong(count), a.length());
- BOOST_CHECK_EQUAL(CORBA::ULong(count), a.maximum());
- for(CORBA::ULong i = 0; i != count; ++i) {
- BOOST_CHECK_EQUAL(int(i), a[i]);
- }
-}
-
-void check_equal(
- tested_seq const & a,
- tested_seq const & b)
-{
- BOOST_CHECK_EQUAL(a.length(), b.length());
- BOOST_CHECK_EQUAL(a.maximum(), b.maximum());
- for(CORBA::ULong i = 0; i != a.length(); ++i) {
- BOOST_CHECK_EQUAL(a[i], b[i]);
- }
-}
-
-BOOST_AUTO_UNIT_TEST(test_default_constructor)
-{
- tested_seq default_constructed;
-
- BOOST_CHECK_EQUAL(CORBA::ULong(0), default_constructed.length());
- BOOST_CHECK_EQUAL(CORBA::ULong(0), default_constructed.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_maximum_constructor)
-{
- CORBA::ULong length = 16;
- tested_seq length_constructed(length);
- BOOST_CHECK_EQUAL(CORBA::ULong(0), length_constructed.length());
- BOOST_CHECK_EQUAL(CORBA::ULong(length), length_constructed.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_copy_constructor_from_default)
-{
- tested_seq default_constructed;
- tested_seq copy_constructed(default_constructed);
- BOOST_CHECK_EQUAL(CORBA::ULong(0), copy_constructed.length());
- BOOST_CHECK_EQUAL(CORBA::ULong(0), copy_constructed.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_copy_constructor_from_length)
-{
- CORBA::ULong length = 16;
- tested_seq length_constructed(length);
- tested_seq copy_constructed_2(length_constructed);
- BOOST_CHECK_EQUAL(CORBA::ULong(0), copy_constructed_2.length());
- BOOST_CHECK_EQUAL(CORBA::ULong(length), copy_constructed_2.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_set_length)
-{
- tested_seq x;
-
- x.length(16);
- BOOST_CHECK_EQUAL(CORBA::ULong(16), x.length());
- BOOST_CHECK(CORBA::ULong(16) <= x.maximum());
-
- x.length(8);
- BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
- BOOST_CHECK(CORBA::ULong(8) <= x.maximum());
-}
-
-BOOST_AUTO_UNIT_TEST(test_setting_and_copy)
-{
- tested_seq a;
- init(16, a);
- check_init(16, a);
-
- tested_seq b(a);
- check_equal(a, b);
-}
-
-BOOST_AUTO_UNIT_TEST(test_setting_and_assign)
-{
- tested_seq a;
- init(16, a);
- check_init(16, a);
-
- tested_seq c;
- c = a;
- check_equal(a, c);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_maximum_constructor)
-{
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
- try
- {
- test_traits::allocbuf_failure_counter = 1;
-
- tested_seq dst(16);
- BOOST_ERROR("Missed exception in constructor");
- }
- catch(local_exception const & )
- {
- }
- catch(...)
- {
- BOOST_ERROR("Unknown exception in constructor");
- }
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_copy_constructor)
-{
- tested_seq src(16); src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
- try
- {
- test_traits::allocbuf_failure_counter = 1;
-
- tested_seq dst(src);
- BOOST_ERROR("Missed exception in copy constructor");
- }
- catch(local_exception const & )
- {
- }
- catch(...)
- {
- BOOST_ERROR("Unknown exception in copy constructor");
- }
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_assignment)
-{
- tested_seq src(16); src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- tested_seq dst(8); dst.length(8);
- dst[0] = 0; dst[6] = 5;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
- try
- {
- test_traits::allocbuf_failure_counter = 1;
- dst = src;
- BOOST_ERROR("Missed exception in assignment");
- }
- catch(local_exception const & ex)
- {
- }
- catch(...)
- {
- BOOST_ERROR("Unexpected exception in assignment");
- }
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-
- BOOST_CHECK_EQUAL(8UL, dst.length());
- BOOST_CHECK_EQUAL(0, dst[0]);
- BOOST_CHECK_EQUAL(5, dst[6]);
-}
-
-BOOST_AUTO_UNIT_TEST(test_exceptions_in_set_length)
-{
- tested_seq src(16); src.length(16);
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- src[i] = i;
-
- long freebuf_calls = test_traits::freebuf_calls;
- long allocbuf_calls = test_traits::allocbuf_calls;
- try
- {
- test_traits::allocbuf_failure_counter = 1;
- src.length(32);
- BOOST_ERROR("Missed exception in length()");
- }
- catch(local_exception const & ex)
- {
- }
- catch(...)
- {
- BOOST_ERROR("Unexpected exception length()");
- }
-
- BOOST_CHECK_EQUAL(
- freebuf_calls,
- test_traits::freebuf_calls);
- BOOST_CHECK_EQUAL(
- allocbuf_calls + 1,
- test_traits::allocbuf_calls);
-
- BOOST_CHECK_EQUAL(16UL, src.length());
- for(CORBA::ULong i = 0; i != 16UL; ++i)
- BOOST_CHECK_EQUAL(int(i), src[i]);
-}
-
-BOOST_AUTO_UNIT_TEST(test_check_index_is_called)
-{
- tested_seq a;
- init(16, a);
-
- try
- {
- a[16] = 16;
- BOOST_ERROR("Missing range error exception");
- }
- catch(std::range_error const &) {}
- catch(...) {
- BOOST_ERROR("Unexpected exception raised");
- }
- check_init(16, a);
-}
-
-int * init_data()
-{
- int * data = tested_seq::allocbuf(16);
- data[0] = 1; data[1] = 4; data[2] = 9;
-
- return data;
-}
-
-void check_data(tested_seq const & a)
-{
- BOOST_CHECK_EQUAL(16UL, a.maximum());
- BOOST_CHECK_EQUAL(8UL, a.length());
- BOOST_CHECK_EQUAL(1, a[0]);
- BOOST_CHECK_EQUAL(4, a[1]);
- BOOST_CHECK_EQUAL(9, a[2]);
-}
-
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_default)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(16, 8, data);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_false)
-{
- int * data = init_data();
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(16, 8, data, false);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_buffer_constructor_true)
-{
- int * data = init_data();
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a(16, 8, data, true);
- check_data(a);
- BOOST_CHECK_EQUAL(true, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_default)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(16, 8, data);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_false)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(16, 8, data, false);
- check_data(a);
- BOOST_CHECK_EQUAL(false, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- BOOST_CHECK_EQUAL(++f, test_traits::freebuf_calls);
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_replace_true)
-{
- int * data = init_data();
-
- long a = test_traits::allocbuf_calls;
- long f = test_traits::freebuf_calls;
- {
- tested_seq a;
- a.replace(16, 8, data, true);
- check_data(a);
- BOOST_CHECK_EQUAL(true, a.release());
- }
- BOOST_CHECK_EQUAL(a, test_traits::allocbuf_calls);
- ++f; ++f;
- BOOST_CHECK_EQUAL(f, test_traits::freebuf_calls);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_const)
-{
- int * data = init_data();
- tested_seq a(16, 8, data, true);
- tested_seq const & b = a;
- BOOST_CHECK_EQUAL(b.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_default)
-{
- int * data = init_data();
- tested_seq a(16, 8, data, true);
- BOOST_CHECK_EQUAL(a.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_false)
-{
- int * data = init_data();
- tested_seq a(16, 8, data, true);
- BOOST_CHECK_EQUAL(a.get_buffer(), data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_true_with_release_false)
-{
- int * data = init_data();
- tested_seq a(16, 8, data, false);
- BOOST_CHECK_EQUAL(static_cast<int*>(0), a.get_buffer(true));
- tested_seq::freebuf(data);
-}
-
-BOOST_AUTO_UNIT_TEST(test_get_buffer_true_with_release_true)
-{
- int * data = init_data();
- tested_seq a(16, 8, data, true);
- BOOST_CHECK_EQUAL(data, a.get_buffer(true));
- tested_seq const & b = a;
- BOOST_CHECK_EQUAL(0UL, b.maximum());
- BOOST_CHECK_EQUAL(0UL, b.length());
- BOOST_CHECK(0 != b.get_buffer());
- BOOST_CHECK(data != b.get_buffer());
- tested_seq::freebuf(data);
-}
-
-#if !defined(BOOST_AUTO_TEST_MAIN)
-// This is just to convince MPC that I do not need a main() to have a
-// program.
-int main() {}
-#endif
diff --git a/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp
index 37f0d22a306..f2123601fa0 100644
--- a/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp
+++ b/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp
@@ -8,7 +8,7 @@
*
* @author Carlos O'Ryan
*/
-#include "sequence.hpp"
+#include "unbounded_value_sequence.hpp"
struct Foo
{
@@ -17,14 +17,14 @@ struct Foo
int main(int,char*[])
{
- typedef TAO::unbounded_sequence<int> int_sequence;
+ typedef TAO::unbounded_value_sequence<int> int_sequence;
int_sequence a;
int_sequence b(23);
a = b;
- typedef TAO::unbounded_sequence<Foo> Foo_sequence;
+ typedef TAO::unbounded_value_sequence<Foo> Foo_sequence;
Foo_sequence c;
Foo_sequence d(32);
@@ -37,5 +37,5 @@ int main(int,char*[])
// of all member function and thus tests the full class. This should
// work across all platforms, even on platforms that do not *require*
// explicit instantiation of templates.
-template class TAO::unbounded_sequence<int>;
-template class TAO::unbounded_sequence<Foo>;
+template class TAO::unbounded_value_sequence<int>;
+template class TAO::unbounded_value_sequence<Foo>;
diff --git a/TAO/tests/Sequence_Unit_Tests/sequence_traits.hpp b/TAO/tests/Sequence_Unit_Tests/allocation_traits.hpp
index 6dbe5d930e0..a96f90516e7 100644
--- a/TAO/tests/Sequence_Unit_Tests/sequence_traits.hpp
+++ b/TAO/tests/Sequence_Unit_Tests/allocation_traits.hpp
@@ -1,44 +1,28 @@
-#ifndef guard_TAO_sequence_traits_hpp
-#define guard_TAO_sequence_traits_hpp
+#ifndef guard_allocation_traits_hpp
+#define guard_allocation_traits_hpp
/**
* @file
*
- * @brief Please see the documentation for generic_sequence.cpp for
- * details.
+ * @brief Details can be found in the documentation for
+ * TAO::details::generic_sequence
*
* $Id$
*
* @author Carlos O'Ryan
*/
-#include "tao/corbafwd.h"
+#include "tao/Basic_Types.h"
namespace TAO
{
namespace details
{
-template<class T>
-struct sequence_traits
+template<typename T, bool dummy>
+struct unbounded_allocation_traits
{
typedef T value_type;
- inline static void check_index(
- CORBA::ULong /* index */,
- CORBA::ULong /* length */,
- CORBA::ULong /* maximum */,
- char const * /* function_name */)
- {
- // Applications and tests can specialize this function to define
- // their own behavior
- }
-};
-
-template<class T>
-struct unbounded_sequence_traits : public sequence_traits<T>
-{
- typedef typename sequence_traits<T>::value_type value_type;
-
inline static CORBA::ULong default_maximum()
{
return 0;
@@ -60,10 +44,10 @@ struct unbounded_sequence_traits : public sequence_traits<T>
}
};
-template<class T, CORBA::ULong MAX>
-struct bounded_sequence_traits : public sequence_traits<T>
+template<typename T, CORBA::ULong MAX, bool dummy>
+struct bounded_allocation_traits
{
- typedef typename sequence_traits<T>::value_type value_type;
+ typedef T value_type;
inline static CORBA::ULong default_maximum()
{
@@ -90,10 +74,9 @@ struct bounded_sequence_traits : public sequence_traits<T>
return MAX;
}
/* static CORBA::ULong const MAXIMUM = MAX; */
-
};
} // namespace details
-} // namespace CORBA
+} // namespace TAO
-#endif // guard_TAO_sequence_traits_hpp
+#endif // guard_allocation_traits_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence.hpp b/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence.hpp
new file mode 100644
index 00000000000..beace540c4c
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence.hpp
@@ -0,0 +1,91 @@
+#ifndef TAO_unbounded_value_sequence_hpp
+#define TAO_unbounded_value_sequence_hpp
+/**
+ * @file
+ *
+ * @brief Implement bounded sequences for types with value-like
+ * semantics.
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include "allocation_traits.hpp"
+#include "value_traits.hpp"
+#include "generic_sequence.hpp"
+
+namespace TAO
+{
+
+template<class T, CORBA::ULong MAX>
+class bounded_value_sequence
+{
+public:
+ // static CORBA::ULong const MAXIMUM = MAX;
+ typedef T value_type;
+ typedef details::bounded_allocation_traits<T,MAX,true> allocation_traits;
+ typedef details::value_traits<T,true> element_traits;
+ typedef details::generic_sequence<T, allocation_traits, element_traits> implementation_type;
+
+ inline bounded_value_sequence()
+ : impl_()
+ {}
+ inline bounded_value_sequence(
+ CORBA::ULong length,
+ T * data,
+ CORBA::Boolean release = false)
+ : impl_(MAX, length, data, release)
+ {}
+ /* Use default ctor, operator= and dtor */
+ inline CORBA::ULong maximum() const {
+ return impl_.maximum();
+ }
+ inline CORBA::Boolean release() const {
+ return impl_.release();
+ }
+ inline CORBA::ULong length() const {
+ return impl_.length();
+ }
+ inline void length(CORBA::ULong length) {
+ impl_.length(length);
+ }
+ inline T const & operator[](CORBA::ULong i) const {
+ return impl_[i];
+ }
+ inline value_type & operator[](CORBA::ULong i) {
+ return impl_[i];
+ }
+ inline void replace(
+ CORBA::ULong length,
+ T * data,
+ CORBA::Boolean release = false) {
+ impl_.replace(MAX, length, data, release);
+ }
+ inline T const * get_buffer() const {
+ return impl_.get_buffer();
+ }
+ inline T * get_buffer(CORBA::Boolean orphan = false) {
+ return impl_.get_buffer(orphan);
+ }
+ inline void swap(bounded_value_sequence & rhs) throw() {
+ impl_.swap(rhs.impl_);
+ }
+ static T * allocbuf(CORBA::ULong maximum) {
+ return implementation_type::allocbuf(maximum);
+ }
+ static T * allocbuf() {
+ return implementation_type::allocbuf(MAX);
+ }
+ static void freebuf(T * buffer)
+ {
+ implementation_type::freebuf(buffer);
+ }
+
+private:
+ implementation_type impl_;
+};
+
+} // namespace TAO
+
+#endif // TAO_unbounded_string_sequence_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence_ut.cpp b/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence_ut.cpp
new file mode 100644
index 00000000000..7cd0e362f20
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/bounded_value_sequence_ut.cpp
@@ -0,0 +1,320 @@
+/**
+ * @file
+ *
+ * @brief Unit test for bounded sequences of value types (integers,
+ * structures, etc.)
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+#include "testing_allocation_traits.hpp"
+#include "testing_range_checking.hpp"
+
+#include "bounded_value_sequence.hpp"
+
+#include "value_sequence_tester.hpp"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+using namespace boost::unit_test_framework;
+using namespace TAO;
+
+CORBA::ULong const MAXIMUM = 32;
+
+typedef details::value_traits<int,true> tested_element_traits;
+typedef details::bounded_allocation_traits<int,MAXIMUM,true> tested_allocation_traits;
+typedef details::range_checking<int,true> range;
+
+typedef bounded_value_sequence<int,MAXIMUM> tested_sequence;
+
+struct Tester
+ : public boost::enable_shared_from_this<Tester>
+{
+ typedef tested_sequence::value_type value_type;
+
+ void add_all(test_suite * ts)
+ {
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_set_length_less_than_maximum,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_true,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_true,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_const,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_true_with_release_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_true_with_release_true,
+ shared_from_this()));
+
+ }
+
+
+ void test_set_length_less_than_maximum()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x;
+
+ x.length(8);
+ BOOST_CHECK_EQUAL(CORBA::ULong(MAXIMUM), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+ }
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::default_buffer_allocation_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ value_type * alloc_and_init_buffer()
+ {
+ value_type * buf = tested_sequence::allocbuf();
+ buf[0] = 1; buf[1] = 4; buf[2] = 9; buf[3] = 16;
+
+ return buf;
+ }
+
+ void test_buffer_constructor_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(4, buffer);
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_buffer_constructor_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(4, buffer, false);
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_buffer_constructor_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(4, buffer, true);
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(true, a.release());
+ }
+ BOOST_CHECK_EQUAL( a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_replace_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a;
+ a.replace(4, buffer);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_replace_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+
+ {
+ tested_sequence a;
+ a.replace(4, buffer, false);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_replace_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+
+ {
+ tested_sequence a;
+ a.replace(4, buffer, true);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(true, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_get_buffer_const()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(4, buffer, true);
+ tested_sequence const & b = a;
+ BOOST_CHECK_EQUAL(b.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(4, buffer, true);
+ BOOST_CHECK_EQUAL(a.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(4, buffer, true);
+ BOOST_CHECK_EQUAL(a.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_true_with_release_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(4, buffer, false);
+ BOOST_CHECK_EQUAL(static_cast<int*>(0), a.get_buffer(true));
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_get_buffer_true_with_release_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::default_buffer_allocation_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(4, buffer, true);
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer(true));
+
+ tested_sequence const & b = a;
+ BOOST_CHECK_EQUAL(MAXIMUM, b.maximum());
+ BOOST_CHECK_EQUAL(0UL, b.length());
+ BOOST_CHECK(0 != b.get_buffer());
+
+ BOOST_CHECK_EQUAL(++c, tested_allocation_traits::default_buffer_allocation_calls);
+
+ BOOST_CHECK(buffer != b.get_buffer());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::default_buffer_allocation_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+};
+
+test_suite *
+init_unit_test_suite(int, char*[])
+{
+ std::auto_ptr<test_suite> ts(
+ BOOST_TEST_SUITE("unbounded value sequence unit test"));
+
+ {
+ boost::shared_ptr<Tester> tester(new Tester);
+ tester->add_all(ts.get());
+ }
+
+ {
+ typedef value_sequence_tester<tested_sequence,tested_allocation_traits> common;
+ boost::shared_ptr<common> tester(new common);
+ tester->add_all(ts.get());
+ }
+
+ return ts.release();
+}
+
+#if 0
+// This is just to convince MPC that I do not need a main() to have a
+// program.
+int main() {}
+#endif
diff --git a/TAO/tests/Sequence_Unit_Tests/generic_sequence.hpp b/TAO/tests/Sequence_Unit_Tests/generic_sequence.hpp
index f5c47ebda23..77e07d21941 100644
--- a/TAO/tests/Sequence_Unit_Tests/generic_sequence.hpp
+++ b/TAO/tests/Sequence_Unit_Tests/generic_sequence.hpp
@@ -13,7 +13,7 @@
* @author Carlos O'Ryan
*/
-#include "sequence_traits.hpp"
+#include "range_checking.hpp"
#include <algorithm>
@@ -22,19 +22,25 @@ namespace TAO
namespace details
{
-template<class T, class TRAITS>
+template<typename T,
+ class ALLOCATION_TRAITS,
+ class ELEMENT_TRAITS>
class generic_sequence
{
public:
typedef T value_type;
- typedef TRAITS traits;
+ typedef ALLOCATION_TRAITS allocation_traits;
+ typedef ELEMENT_TRAITS element_traits;
+ typedef range_checking<value_type,true> range;
generic_sequence()
- : maximum_(traits::default_maximum())
+ : maximum_(allocation_traits::default_maximum())
, length_(0)
- , buffer_(traits::default_buffer_allocation())
+ , buffer_(allocation_traits::default_buffer_allocation())
, release_(true)
{
+ element_traits::zero_range(
+ buffer_, buffer_ + maximum_);
}
explicit generic_sequence(CORBA::ULong maximum)
@@ -43,6 +49,8 @@ public:
, buffer_(allocbuf(maximum_))
, release_(true)
{
+ element_traits::zero_range(
+ buffer_, buffer_ + maximum_);
}
generic_sequence(
@@ -65,7 +73,8 @@ public:
{
generic_sequence tmp(rhs.maximum_);
tmp.length_ = rhs.length_;
- std::copy(rhs.buffer_, rhs.buffer_ + rhs.length_, tmp.buffer_);
+ element_traits::copy_range(
+ rhs.buffer_, rhs.buffer_ + rhs.length_, tmp.buffer_);
swap(tmp);
}
@@ -103,24 +112,34 @@ public:
{
if (length < maximum_ || length < length_)
{
+ if (length_ < length)
+ {
+ // TODO Not exception-safe...
+ element_traits::initialize_range(
+ buffer_ + length_, buffer_ + length);
+ }
length_ = length;
return;
}
generic_sequence tmp(length); tmp.length_ = length;
- std::copy(buffer_, buffer_ + length_, tmp.buffer_);
+ element_traits::copy_range(
+ buffer_, buffer_ + length_, tmp.buffer_);
+ element_traits::initialize_range(
+ tmp.buffer_ + length_, tmp.buffer_ + length);
+
swap(tmp);
}
value_type const & operator[](CORBA::ULong i) const
{
- traits::check_index(i, length_, maximum_, "operator[]() const");
+ range::check(i, length_, maximum_, "operator[]() const");
return buffer_[i];
}
value_type & operator[](CORBA::ULong i)
{
- traits::check_index(i, length_, maximum_, "operator[]() non-const");
+ range::check(i, length_, maximum_, "operator[]() non-const");
return buffer_[i];
}
@@ -175,12 +194,12 @@ public:
static T * allocbuf(CORBA::ULong maximum)
{
- return traits::allocbuf(maximum);
+ return allocation_traits::allocbuf(maximum);
}
static void freebuf(T * buffer)
{
- traits::freebuf(buffer);
+ allocation_traits::freebuf(buffer);
}
private:
diff --git a/TAO/tests/Sequence_Unit_Tests/range_checking.hpp b/TAO/tests/Sequence_Unit_Tests/range_checking.hpp
new file mode 100644
index 00000000000..920ba0a03ac
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/range_checking.hpp
@@ -0,0 +1,53 @@
+#ifndef guard_range_checking_hpp
+#define guard_range_checking_hpp
+/**
+ * @file
+ *
+ * @brief Details can be found in the documentation for
+ * TAO::details::generic_sequence
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include "tao/Basic_Types.h"
+
+namespace TAO
+{
+namespace details
+{
+
+/**
+ * @struct
+ *
+ * @brief Configurable trait to check the range in operator[] access
+ * to sequences.
+ *
+ * The sequence classes in TAO delegate on
+ * range_checking<T>::check() to check the range of an operator[]
+ * access. Applications can specialize this class to detect
+ * out-of-range accesses and take appropriate action (debug messages,
+ * throw exceptions, etc.)
+ *
+ */
+template<typename T, bool dummy>
+struct range_checking
+{
+ typedef T value_type;
+
+ inline static void check(
+ CORBA::ULong /* index */,
+ CORBA::ULong /* length */,
+ CORBA::ULong /* maximum */,
+ char const * /* function_name */)
+ {
+ // Applications and tests can specialize this function to define
+ // their own behavior
+ }
+};
+
+} // namespace details
+} // namespace TAO
+
+#endif // guard_range_checking_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/run_test.pl b/TAO/tests/Sequence_Unit_Tests/run_test.pl
index 8e1de90d32c..5baaa6899cd 100755
--- a/TAO/tests/Sequence_Unit_Tests/run_test.pl
+++ b/TAO/tests/Sequence_Unit_Tests/run_test.pl
@@ -11,8 +11,8 @@ use strict;
my $final_result = 0;
-foreach my $process (qw(Unbounded_Primitive_Types
- Bounded_Primitive_Types
+foreach my $process (qw(unbounded_value_sequence_ut
+ bounded_value_sequence_ut
Unbounded_Simple_Types
Bounded_Simple_Types)) {
diff --git a/TAO/tests/Sequence_Unit_Tests/sequence.hpp b/TAO/tests/Sequence_Unit_Tests/sequence.hpp
deleted file mode 100644
index e5b2d044559..00000000000
--- a/TAO/tests/Sequence_Unit_Tests/sequence.hpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#ifndef guard_TAO_sequence_hpp
-#define guard_TAO_sequence_hpp
-/**
- * @file
- *
- * @brief Implement both bounded and unbounded sequences of
- * self-managed types.
- *
- * $Id$
- *
- * @author Carlos O'Ryan
- */
-
-#include "generic_sequence.hpp"
-
-namespace TAO
-{
-
-template<class T>
-class unbounded_sequence
-{
-public:
- typedef T value_type;
- typedef details::unbounded_sequence_traits<T> traits;
- typedef details::generic_sequence<T, traits> implementation_type;
-
- inline unbounded_sequence()
- : impl_()
- {}
- inline /* explicit */ unbounded_sequence(CORBA::ULong maximum)
- : impl_(maximum)
- {}
- inline unbounded_sequence(
- CORBA::ULong maximum,
- CORBA::ULong length,
- T * data,
- CORBA::Boolean release = false)
- : impl_(maximum, length, data, release)
- {}
- /* Use default ctor, operator= and dtor */
- inline CORBA::ULong maximum() const {
- return impl_.maximum();
- }
- inline CORBA::Boolean release() const {
- return impl_.release();
- }
- inline CORBA::ULong length() const {
- return impl_.length();
- }
- inline void length(CORBA::ULong length) {
- impl_.length(length);
- }
- inline T const & operator[](CORBA::ULong i) const {
- return impl_[i];
- }
- inline value_type & operator[](CORBA::ULong i) {
- return impl_[i];
- }
- inline void replace(
- CORBA::ULong maximum,
- CORBA::ULong length,
- T * data,
- CORBA::Boolean release = false) {
- impl_.replace(maximum, length, data, release);
- }
- inline T const * get_buffer() const {
- return impl_.get_buffer();
- }
- inline T * get_buffer(CORBA::Boolean orphan = false) {
- return impl_.get_buffer(orphan);
- }
- inline void swap(unbounded_sequence & rhs) throw() {
- impl_.swap(rhs.impl_);
- }
- static T * allocbuf(CORBA::ULong maximum) {
- return implementation_type::allocbuf(maximum);
- }
- static void freebuf(T * buffer)
- {
- implementation_type::freebuf(buffer);
- }
-
-private:
- implementation_type impl_;
-};
-
-template<class T, CORBA::ULong MAX>
-class bounded_sequence
-{
-public:
- // static const CORBA::ULong MAXIMUM = MAX;
- typedef T value_type;
- typedef details::bounded_sequence_traits<T,MAX> traits;
- typedef details::generic_sequence<T, traits> implementation_type;
-
- inline bounded_sequence()
- : impl_()
- {}
- inline bounded_sequence(
- CORBA::ULong length,
- T * data,
- CORBA::Boolean release = false)
- : impl_(MAX, length, data, release)
- {}
- /* Use default ctor, operator= and dtor */
- inline CORBA::ULong maximum() const {
- return impl_.maximum();
- }
- inline CORBA::Boolean release() const {
- return impl_.release();
- }
- inline CORBA::ULong length() const {
- return impl_.length();
- }
- inline void length(CORBA::ULong length) {
- impl_.length(length);
- }
- inline T const & operator[](CORBA::ULong i) const {
- return impl_[i];
- }
- inline value_type & operator[](CORBA::ULong i) {
- return impl_[i];
- }
- inline void replace(
- CORBA::ULong length,
- T * data,
- CORBA::Boolean release = false) {
- impl_.replace(MAX, length, data, release);
- }
- inline T const * get_buffer() const {
- return impl_.get_buffer();
- }
- inline T * get_buffer(CORBA::Boolean orphan = false) {
- return impl_.get_buffer(orphan);
- }
- inline void swap(bounded_sequence & rhs) throw() {
- impl_.swap(rhs.impl_);
- }
- static T * allocbuf(CORBA::ULong maximum) {
- return implementation_type::allocbuf(maximum);
- }
- static T * allocbuf() {
- return implementation_type::allocbuf(MAX);
- }
- static void freebuf(T * buffer)
- {
- implementation_type::freebuf(buffer);
- }
-
-private:
- implementation_type impl_;
-};
-
-} // namespace TAO
-
-#endif // guard_TAO_sequence_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/testing_allocation_traits.hpp b/TAO/tests/Sequence_Unit_Tests/testing_allocation_traits.hpp
new file mode 100644
index 00000000000..541a8ff2fe4
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/testing_allocation_traits.hpp
@@ -0,0 +1,91 @@
+#ifndef guard_testing_sequence_traits_hpp
+#define guard_testing_sequence_traits_hpp
+/**
+ * @file
+ *
+ * @brief Specialize the allocation traits in a manner suitable for
+ * testing.
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include "allocation_traits.hpp"
+#include "testing_exception.hpp"
+
+template<typename T, class base>
+struct testing_allocation_traits : public base
+{
+ static long allocbuf_calls;
+ static long freebuf_calls;
+ static long calls_until_failure_in_allocbuf;
+
+ static long default_buffer_allocation_calls;
+ static long calls_until_failure_in_default_buffer_allocation;
+
+ typedef typename base::value_type value_type;
+
+ inline static value_type * default_buffer_allocation()
+ {
+ ++default_buffer_allocation_calls;
+ if (--calls_until_failure_in_default_buffer_allocation == 0)
+ {
+ throw testing_exception();
+ }
+ return base::default_buffer_allocation();
+ }
+
+ inline static value_type * allocbuf(CORBA::ULong maximum)
+ {
+ ++allocbuf_calls;
+ if (--calls_until_failure_in_allocbuf == 0)
+ {
+ throw testing_exception();
+ }
+ return base::allocbuf(maximum);
+ }
+
+ inline static void freebuf(value_type * buffer)
+ {
+ ++freebuf_calls;
+ base::freebuf(buffer);
+ }
+};
+
+template<typename T, class base>
+long testing_allocation_traits<T,base>::allocbuf_calls = 0;
+
+template<typename T, class base>
+long testing_allocation_traits<T,base>::freebuf_calls = 0;
+
+template<typename T, class base>
+long testing_allocation_traits<T,base>::calls_until_failure_in_allocbuf = 0;
+
+template<typename T, class base>
+long testing_allocation_traits<T,base>::default_buffer_allocation_calls = 0;
+
+template<typename T, class base>
+long testing_allocation_traits<T,base>::calls_until_failure_in_default_buffer_allocation = 0;
+
+namespace TAO
+{
+namespace details
+{
+
+template<typename T>
+struct unbounded_allocation_traits<T,true>
+ : public testing_allocation_traits<T, unbounded_allocation_traits<T,false> >
+{
+};
+
+template<typename T, CORBA::ULong MAX>
+struct bounded_allocation_traits<T,MAX,true>
+ : public testing_allocation_traits<T, bounded_allocation_traits<T,MAX,false> >
+{
+};
+
+} // namespace details
+} // namespace TAO
+
+#endif // guard_testing_sequence_traits_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/testing_exception.hpp b/TAO/tests/Sequence_Unit_Tests/testing_exception.hpp
new file mode 100644
index 00000000000..2fc4c540197
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/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
diff --git a/TAO/tests/Sequence_Unit_Tests/testing_range_checking.hpp b/TAO/tests/Sequence_Unit_Tests/testing_range_checking.hpp
new file mode 100644
index 00000000000..d3f6b918bed
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/testing_range_checking.hpp
@@ -0,0 +1,57 @@
+#ifndef guard_testing_range_checking_hpp
+#define guard_testing_range_checking_hpp
+/**
+ * @file
+ *
+ * @brief Specialize the range_checking traits in a manner suitable
+ * for testing.
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include "range_checking.hpp"
+
+#include <sstream>
+#include <stdexcept>
+
+template<typename T>
+struct testing_range_checking
+{
+ typedef T value_type;
+
+ inline static void check(
+ CORBA::ULong index,
+ CORBA::ULong length,
+ CORBA::ULong maximum,
+ char const * function_name)
+ {
+ if (index < length) {
+ return;
+ }
+ std::ostringstream error;
+ error << "Out of range access in " << function_name
+ << ", index=" << index
+ << ", length=" << length
+ << ", maximum=" << maximum
+ << ", class=unbounded_sequence<int>";
+ throw std::range_error(error.str());
+ }
+};
+
+namespace TAO
+{
+namespace details
+{
+
+template<typename T>
+struct range_checking<T,true>
+ : public testing_range_checking<T>
+{
+};
+
+} // namespace details
+} // namespace TAO
+
+#endif // guard_testing_range_checking_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence.hpp b/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence.hpp
new file mode 100644
index 00000000000..e81f1f937eb
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence.hpp
@@ -0,0 +1,92 @@
+#ifndef TAO_unbounded_value_sequence_hpp
+#define TAO_unbounded_value_sequence_hpp
+/**
+ * @file
+ *
+ * @brief Implement unbounded sequences for types with value-like
+ * semantics.
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include "allocation_traits.hpp"
+#include "value_traits.hpp"
+#include "generic_sequence.hpp"
+
+namespace TAO
+{
+
+template<class T>
+class unbounded_value_sequence
+{
+public:
+ typedef T value_type;
+ typedef details::unbounded_allocation_traits<T,true> allocation_traits;
+ typedef details::value_traits<T,true> element_traits;
+ typedef details::generic_sequence<T, allocation_traits, element_traits> implementation_type;
+
+ inline unbounded_value_sequence()
+ : impl_()
+ {}
+ inline /* explicit */ unbounded_value_sequence(CORBA::ULong maximum)
+ : impl_(maximum)
+ {}
+ inline unbounded_value_sequence(
+ CORBA::ULong maximum,
+ CORBA::ULong length,
+ T * data,
+ CORBA::Boolean release = false)
+ : impl_(maximum, length, data, release)
+ {}
+ /* Use default ctor, operator= and dtor */
+ inline CORBA::ULong maximum() const {
+ return impl_.maximum();
+ }
+ inline CORBA::Boolean release() const {
+ return impl_.release();
+ }
+ inline CORBA::ULong length() const {
+ return impl_.length();
+ }
+ inline void length(CORBA::ULong length) {
+ impl_.length(length);
+ }
+ inline T const & operator[](CORBA::ULong i) const {
+ return impl_[i];
+ }
+ inline value_type & operator[](CORBA::ULong i) {
+ return impl_[i];
+ }
+ inline void replace(
+ CORBA::ULong maximum,
+ CORBA::ULong length,
+ T * data,
+ CORBA::Boolean release = false) {
+ impl_.replace(maximum, length, data, release);
+ }
+ inline T const * get_buffer() const {
+ return impl_.get_buffer();
+ }
+ inline T * get_buffer(CORBA::Boolean orphan = false) {
+ return impl_.get_buffer(orphan);
+ }
+ inline void swap(unbounded_value_sequence & rhs) throw() {
+ impl_.swap(rhs.impl_);
+ }
+ static T * allocbuf(CORBA::ULong maximum) {
+ return implementation_type::allocbuf(maximum);
+ }
+ static void freebuf(T * buffer) {
+ implementation_type::freebuf(buffer);
+ }
+
+private:
+ implementation_type impl_;
+};
+
+} // namespace TAO
+
+#endif // TAO_unbounded_string_sequence_hpp
+
diff --git a/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence_ut.cpp b/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence_ut.cpp
new file mode 100644
index 00000000000..03396f439a1
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/unbounded_value_sequence_ut.cpp
@@ -0,0 +1,450 @@
+/**
+ * @file
+ *
+ * @brief Unit test for unbounded sequences of value types (integers,
+ * structures, etc.)
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+#include "testing_allocation_traits.hpp"
+#include "testing_range_checking.hpp"
+
+#include "unbounded_value_sequence.hpp"
+
+#include "value_sequence_tester.hpp"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+using namespace boost::unit_test_framework;
+using namespace TAO;
+
+typedef details::value_traits<int,true> tested_element_traits;
+typedef details::unbounded_allocation_traits<int,true> tested_allocation_traits;
+typedef details::range_checking<int,true> range;
+
+typedef unbounded_value_sequence<int> tested_sequence;
+
+struct Tester
+ : public boost::enable_shared_from_this<Tester>
+{
+ typedef tested_sequence::value_type value_type;
+
+ void add_all(test_suite * ts)
+ {
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_ulong_constructor, shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_copy_constructor_from_ulong,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_assignment_from_ulong,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_exception_in_ulong_constructor,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_set_length_less_than_maximum,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_set_length_more_than_maximum,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_exception_in_set_length,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_buffer_constructor_true,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_replace_true,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_const,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_true_with_release_false,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &Tester::test_get_buffer_true_with_release_true,
+ shared_from_this()));
+
+ }
+
+ void test_copy_constructor_from_ulong()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x(16);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ x.length(8);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+
+ tested_sequence y(x);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), y.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), y.length());
+ BOOST_CHECK_EQUAL(true, y.release());
+ }
+ f += 2;
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_assignment_from_ulong()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x(16);
+ x.length(8);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+
+ tested_sequence y;
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+
+ y = x;
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), y.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), y.length());
+ BOOST_CHECK_EQUAL(true, y.release());
+ }
+ f += 2;
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_ulong_constructor()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x(16);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(0), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+ }
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_exception_in_ulong_constructor()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_allocation_traits::calls_until_failure_in_allocbuf = 1;
+ BOOST_CHECK_THROW(tested_sequence x(16), testing_exception);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ }
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_set_length_less_than_maximum()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x(16);
+
+ x.length(8);
+ BOOST_CHECK_EQUAL(CORBA::ULong(16), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+ }
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_set_length_more_than_maximum()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x(16);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+
+ x.length(32);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(32), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+ }
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_exception_in_set_length()
+ {
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x;
+
+ long a = tested_allocation_traits::allocbuf_calls;
+ tested_allocation_traits::calls_until_failure_in_allocbuf = 1;
+ BOOST_CHECK_THROW(x.length(8), testing_exception);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ }
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ value_type * alloc_and_init_buffer()
+ {
+ value_type * buf = tested_sequence::allocbuf(8);
+ buf[0] = 1; buf[1] = 4; buf[2] = 9; buf[3] = 16;
+
+ return buf;
+ }
+
+ void test_buffer_constructor_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(8, 4, buffer);
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_buffer_constructor_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(8, 4, buffer, false);
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_buffer_constructor_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(8, 4, buffer, true);
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(true, a.release());
+ }
+ BOOST_CHECK_EQUAL( a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_replace_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a;
+ a.replace(8, 4, buffer);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_replace_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+
+ {
+ tested_sequence a;
+ a.replace(8, 4, buffer, false);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(false, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_replace_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+
+ {
+ tested_sequence a;
+ a.replace(8, 4, buffer, true);
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(8), a.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(4), a.length());
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer());
+ BOOST_CHECK_EQUAL(int( 1), a[0]);
+ BOOST_CHECK_EQUAL(int( 4), a[1]);
+ BOOST_CHECK_EQUAL(int( 9), a[2]);
+ BOOST_CHECK_EQUAL(int(16), a[3]);
+ BOOST_CHECK_EQUAL(true, a.release());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_get_buffer_const()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(8, 4, buffer, true);
+ tested_sequence const & b = a;
+ BOOST_CHECK_EQUAL(b.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_default()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(8, 4, buffer, true);
+ BOOST_CHECK_EQUAL(a.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(8, 4, buffer, true);
+ BOOST_CHECK_EQUAL(a.get_buffer(), buffer);
+ }
+
+ void test_get_buffer_true_with_release_false()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ tested_sequence a(8, 4, buffer, false);
+ BOOST_CHECK_EQUAL(static_cast<int*>(0), a.get_buffer(true));
+ tested_sequence::freebuf(buffer);
+ }
+
+ void test_get_buffer_true_with_release_true()
+ {
+ value_type * buffer = alloc_and_init_buffer();
+ long c = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence a(8, 4, buffer, true);
+ BOOST_CHECK_EQUAL(buffer, a.get_buffer(true));
+
+ tested_sequence const & b = a;
+ BOOST_CHECK_EQUAL(0UL, b.maximum());
+ BOOST_CHECK_EQUAL(0UL, b.length());
+ BOOST_CHECK(0 != b.get_buffer());
+
+ BOOST_CHECK_EQUAL(++c, tested_allocation_traits::allocbuf_calls);
+
+ BOOST_CHECK(buffer != b.get_buffer());
+ }
+ BOOST_CHECK_EQUAL( c, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ tested_sequence::freebuf(buffer);
+ }
+
+};
+
+test_suite *
+init_unit_test_suite(int, char*[])
+{
+ std::auto_ptr<test_suite> ts(
+ BOOST_TEST_SUITE("unbounded value sequence unit test"));
+
+ {
+ boost::shared_ptr<Tester> tester(new Tester);
+ tester->add_all(ts.get());
+ }
+
+ {
+ typedef value_sequence_tester<tested_sequence,tested_allocation_traits> common;
+ boost::shared_ptr<common> tester(new common);
+ tester->add_all(ts.get());
+ }
+
+ return ts.release();
+}
+
+#if 0
+// This is just to convince MPC that I do not need a main() to have a
+// program.
+int main() {}
+#endif
diff --git a/TAO/tests/Sequence_Unit_Tests/value_sequence_tester.hpp b/TAO/tests/Sequence_Unit_Tests/value_sequence_tester.hpp
new file mode 100644
index 00000000000..e780b7ea198
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/value_sequence_tester.hpp
@@ -0,0 +1,239 @@
+#ifndef guard_value_sequence_tester_hpp
+#define guard_value_sequence_tester_hpp
+/**
+ * @file
+ *
+ * @brief Helper class to implement tests for *_value_sequence
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+template<class tested_sequence,
+ class tested_allocation_traits>
+struct value_sequence_tester
+ : public boost::enable_shared_from_this<
+ value_sequence_tester<
+ tested_sequence,tested_allocation_traits> >
+{
+ typedef typename tested_sequence::value_type value_type;
+
+ void add_all(boost::unit_test_framework::test_suite * ts)
+ {
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_default_constructor,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_copy_constructor_from_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_index_accessor,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_index_modifier,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_index_checking,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_copy_constructor_values,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_assignment_from_default,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_assignment_values,
+ shared_from_this()));
+
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_exception_in_copy_constructor,
+ shared_from_this()));
+ ts->add(BOOST_CLASS_TEST_CASE(
+ &value_sequence_tester::test_exception_in_assignment,
+ shared_from_this()));
+ }
+
+
+ void test_default_constructor()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x;
+
+ BOOST_CHECK_EQUAL(
+ CORBA::ULong(tested_allocation_traits::default_maximum()),
+ x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(0), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+ }
+ BOOST_CHECK_EQUAL( a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+
+ void test_copy_constructor_from_default()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x;
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(
+ CORBA::ULong(tested_allocation_traits::default_maximum()),
+ x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(0), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+
+ tested_sequence y(x);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(x.maximum(), y.maximum());
+ BOOST_CHECK_EQUAL(x.length(), y.length());
+ BOOST_CHECK_EQUAL(x.release(), y.release());
+ }
+ f += 2;
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_index_accessor()
+ {
+ tested_sequence x;
+ x.length(8);
+
+ tested_sequence const & y = x;
+ int const & z = y[4];
+ BOOST_CHECK_EQUAL(z, y[4]);
+ }
+
+ void test_index_modifier()
+ {
+ tested_sequence x;
+ x.length(8);
+
+ tested_sequence const & y = x;
+ int const & z = y[4];
+ x[4] = 4;
+ BOOST_CHECK_EQUAL(4, x[4]);
+ BOOST_CHECK_EQUAL(4, y[4]);
+ BOOST_CHECK_EQUAL(4, z);
+ }
+
+ void test_index_checking()
+ {
+ tested_sequence x;
+ x.length(8);
+
+ tested_sequence const & y = x;
+ int z = 0;
+
+ BOOST_CHECK_THROW(z = y[32], std::range_error);
+ BOOST_CHECK_THROW(x[32] = z, std::range_error);
+ }
+
+ void test_copy_constructor_values()
+ {
+ tested_sequence a;
+ a.length(16);
+ for(CORBA::ULong i = 0; i != 16; ++i) a[i] = i*i;
+
+ tested_sequence b(a);
+ BOOST_CHECK_EQUAL(a.length(), b.length());
+ for(CORBA::ULong i = 0; i != a.length(); ++i)
+ {
+ BOOST_CHECK_MESSAGE(a[i] == b[i],
+ "Mismatched elements at index " << i);
+ }
+ }
+
+ void test_assignment_from_default()
+ {
+ long a = tested_allocation_traits::allocbuf_calls;
+ long f = tested_allocation_traits::freebuf_calls;
+ {
+ tested_sequence x;
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(
+ CORBA::ULong(tested_allocation_traits::default_maximum()),
+ x.maximum());
+ BOOST_CHECK_EQUAL(CORBA::ULong(0), x.length());
+ BOOST_CHECK_EQUAL(true, x.release());
+
+ tested_sequence y;
+ BOOST_CHECK_EQUAL(a, tested_allocation_traits::allocbuf_calls);
+
+ y = x;
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ BOOST_CHECK_EQUAL(x.maximum(), y.maximum());
+ BOOST_CHECK_EQUAL(x.length(), y.length());
+ BOOST_CHECK_EQUAL(x.release(), y.release());
+ }
+ f += 2;
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_assignment_values()
+ {
+ tested_sequence a;
+ a.length(16);
+ for(CORBA::ULong i = 0; i != 16; ++i) a[i] = i*i;
+
+ tested_sequence b;
+ b = a;
+ BOOST_CHECK_EQUAL(a.maximum(), b.maximum());
+ BOOST_CHECK_EQUAL(a.length(), b.length());
+ BOOST_CHECK_EQUAL(a.release(), b.release());
+ for(CORBA::ULong i = 0; i != a.length(); ++i)
+ {
+ BOOST_CHECK_MESSAGE(a[i] == b[i],
+ "Mismatched elements at index " << i);
+ }
+ }
+
+ void test_exception_in_copy_constructor()
+ {
+ long f;
+ {
+ tested_sequence x; x.length(8);
+
+ f = tested_allocation_traits::freebuf_calls;
+
+ long a = tested_allocation_traits::allocbuf_calls;
+ tested_allocation_traits::calls_until_failure_in_allocbuf = 1;
+ BOOST_CHECK_THROW(tested_sequence y(x), testing_exception);
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ }
+ BOOST_CHECK_EQUAL(++f, tested_allocation_traits::freebuf_calls);
+ }
+
+ void test_exception_in_assignment()
+ {
+ long f;
+ {
+ tested_sequence x; x.length(2);
+
+ tested_sequence y; y.length(3);
+
+ long a = tested_allocation_traits::allocbuf_calls;
+ f = tested_allocation_traits::freebuf_calls;
+ tested_allocation_traits::calls_until_failure_in_allocbuf = 1;
+ BOOST_CHECK_THROW(y = x, testing_exception);
+
+ BOOST_CHECK_EQUAL(++a, tested_allocation_traits::allocbuf_calls);
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+
+ BOOST_CHECK_EQUAL(CORBA::ULong(3), y.length());
+ }
+ ++f /* for x */; ++f /* for y */;
+ BOOST_CHECK_EQUAL( f, tested_allocation_traits::freebuf_calls);
+ }
+
+};
+
+#endif // guard_value_sequence_tester_hpp
diff --git a/TAO/tests/Sequence_Unit_Tests/value_traits.hpp b/TAO/tests/Sequence_Unit_Tests/value_traits.hpp
new file mode 100644
index 00000000000..e8b96c65be3
--- /dev/null
+++ b/TAO/tests/Sequence_Unit_Tests/value_traits.hpp
@@ -0,0 +1,44 @@
+#ifndef guard_value_traits_hpp
+#define guard_value_traits_hpp
+/**
+ * @file
+ *
+ * @brief Implement the element manipulation traits for types with
+ * value-like semantics.
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+
+#include <algorithm>
+
+namespace TAO
+{
+namespace details
+{
+
+template<typename T, bool dummy>
+struct value_traits
+{
+ typedef T value_type;
+
+ inline static void zero_range(
+ value_type * /* begin */, value_type * /* end */)
+ {}
+
+ inline static void initialize_range(
+ value_type * /* begin */, value_type * /* end */)
+ {}
+
+ inline static void copy_range(
+ value_type * begin, value_type * end, value_type *dst)
+ {
+ std::copy(begin, end, dst);
+ }
+};
+
+} // namespace details
+} // namespace CORBA
+
+#endif // guard_value_traits_hpp