diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2004-09-22 00:32:03 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2004-09-22 00:32:03 +0000 |
commit | e25db3aefe4be43b8bf17d90aaeb4964f5ca1b54 (patch) | |
tree | a75e5a4723b59ef21731155ccddb53fbf72fbf83 | |
parent | 1786c565d31b365d33f619efabc67247a920ce9f (diff) | |
download | ATCD-e25db3aefe4be43b8bf17d90aaeb4964f5ca1b54.tar.gz |
Tue Sep 21 20:15:01 2004 Carlos O'Ryan <coryan@atdesk.com>
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 |