sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "cppunit/cppunit_proxy.h" sl@0: sl@0: #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) sl@0: using namespace std; sl@0: #endif sl@0: sl@0: // sl@0: // TestCase class sl@0: // sl@0: class UninitializedTest : public CPPUNIT_NS::TestCase sl@0: { sl@0: CPPUNIT_TEST_SUITE(UninitializedTest); sl@0: CPPUNIT_TEST(copy_test); sl@0: //CPPUNIT_TEST(fill_test); sl@0: //CPPUNIT_TEST(fill_n_test); sl@0: CPPUNIT_TEST_SUITE_END(); sl@0: sl@0: protected: sl@0: void copy_test(); sl@0: void fill_test(); sl@0: void fill_n_test(); sl@0: }; sl@0: sl@0: CPPUNIT_TEST_SUITE_REGISTRATION(UninitializedTest); sl@0: sl@0: struct NotTrivialCopyStruct { sl@0: NotTrivialCopyStruct() : member(0) {} sl@0: NotTrivialCopyStruct(NotTrivialCopyStruct const&) : member(1) {} sl@0: sl@0: int member; sl@0: }; sl@0: sl@0: struct TrivialCopyStruct { sl@0: TrivialCopyStruct() : member(0) {} sl@0: TrivialCopyStruct(TrivialCopyStruct const&) : member(1) {} sl@0: sl@0: int member; sl@0: }; sl@0: sl@0: struct TrivialInitStruct { sl@0: TrivialInitStruct() sl@0: { ++nbConstructorCalls; } sl@0: sl@0: static size_t nbConstructorCalls; sl@0: }; sl@0: sl@0: size_t TrivialInitStruct::nbConstructorCalls = 0; sl@0: sl@0: #if defined (STLPORT) sl@0: namespace std sl@0: { sl@0: _STLP_TEMPLATE_NULL sl@0: struct __type_traits { sl@0: typedef __false_type has_trivial_default_constructor; sl@0: //This is a wrong declaration just to check that internaly a simple memcpy is called: sl@0: typedef __true_type has_trivial_copy_constructor; sl@0: typedef __true_type has_trivial_assignment_operator; sl@0: typedef __true_type has_trivial_destructor; sl@0: typedef __false_type is_POD_type; sl@0: }; sl@0: sl@0: _STLP_TEMPLATE_NULL sl@0: struct __type_traits { sl@0: //This is a wrong declaration just to check that internaly no initialization is done: sl@0: typedef __true_type has_trivial_default_constructor; sl@0: typedef __true_type has_trivial_copy_constructor; sl@0: typedef __true_type has_trivial_assignment_operator; sl@0: typedef __true_type has_trivial_destructor; sl@0: typedef __false_type is_POD_type; sl@0: }; sl@0: } sl@0: #endif sl@0: sl@0: struct base {}; sl@0: struct derived : public base {}; sl@0: sl@0: // sl@0: // tests implementation sl@0: // sl@0: void UninitializedTest::copy_test() sl@0: { sl@0: { sl@0: //Random iterators sl@0: { sl@0: vector src(10); sl@0: vector dst(10); sl@0: uninitialized_copy(src.begin(), src.end(), dst.begin()); sl@0: vector::const_iterator it(dst.begin()), end(dst.end()); sl@0: for (; it != end; ++it) { sl@0: CPPUNIT_ASSERT( (*it).member == 1 ); sl@0: } sl@0: } sl@0: { sl@0: /** Note: we use static arrays here so the iterators are always sl@0: pointers, even in debug mode. */ sl@0: size_t const count = 10; sl@0: TrivialCopyStruct src[count]; sl@0: TrivialCopyStruct dst[count]; sl@0: sl@0: TrivialCopyStruct* it = src + 0; sl@0: TrivialCopyStruct* end = src + count; sl@0: for (; it != end; ++it) { sl@0: (*it).member = 0; sl@0: } sl@0: sl@0: uninitialized_copy(src+0, src+count, dst+0); sl@0: for (it = dst+0, end = dst+count; it != end; ++it) { sl@0: #if defined (STLPORT) sl@0: /* If the member is 1, it means that library has not found any sl@0: optimization oportunity and called the regular copy-ctor instead. */ sl@0: CPPUNIT_ASSERT( (*it).member == 0 ); sl@0: #else sl@0: CPPUNIT_ASSERT( (*it).member == 1 ); sl@0: #endif sl@0: } sl@0: } sl@0: } sl@0: sl@0: { sl@0: //Bidirectional iterator sl@0: { sl@0: vector src(10); sl@0: list dst(10); sl@0: sl@0: list::iterator it(dst.begin()), end(dst.end()); sl@0: for (; it != end; ++it) { sl@0: (*it).member = -1; sl@0: } sl@0: sl@0: uninitialized_copy(src.begin(), src.end(), dst.begin()); sl@0: sl@0: for (it = dst.begin(); it != end; ++it) { sl@0: CPPUNIT_ASSERT( (*it).member == 1 ); sl@0: } sl@0: } sl@0: sl@0: { sl@0: list src(10); sl@0: vector dst(10); sl@0: sl@0: vector::iterator it(dst.begin()), end(dst.end()); sl@0: for (; it != end; ++it) { sl@0: (*it).member = -1; sl@0: } sl@0: sl@0: uninitialized_copy(src.begin(), src.end(), dst.begin()); sl@0: sl@0: for (it = dst.begin(); it != end; ++it) { sl@0: CPPUNIT_ASSERT( (*it).member == 1 ); sl@0: } sl@0: } sl@0: } sl@0: sl@0: { sl@0: //Using containers of native types: sl@0: #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) sl@0: { sl@0: vector src; sl@0: int i; sl@0: for (i = -5; i < 6; ++i) { sl@0: src.push_back(i); sl@0: } sl@0: sl@0: //Building a vector result in a uninitialized_copy call internally sl@0: vector dst(src.begin(), src.end()); sl@0: vector::const_iterator it(dst.begin()); sl@0: for (i = -5; i < 6; ++i, ++it) { sl@0: CPPUNIT_ASSERT( *it == (unsigned int)i ); sl@0: } sl@0: } sl@0: sl@0: { sl@0: vector src; sl@0: char i; sl@0: for (i = -5; i < 6; ++i) { sl@0: src.push_back(i); sl@0: } sl@0: sl@0: //Building a vector result in a uninitialized_copy call internally sl@0: vector dst(src.begin(), src.end()); sl@0: vector::const_iterator it(dst.begin()); sl@0: for (i = -5; i < 6; ++i, ++it) { sl@0: CPPUNIT_ASSERT( *it == (unsigned int)i ); sl@0: } sl@0: } sl@0: sl@0: { sl@0: vector src; sl@0: int i; sl@0: for (i = -5; i < 6; ++i) { sl@0: src.push_back(i); sl@0: } sl@0: sl@0: //Building a vector result in a uninitialized_copy call internally sl@0: vector dst(src.begin(), src.end()); sl@0: vector::const_iterator it(dst.begin()); sl@0: for (i = -5; i < 6; ++i, ++it) { sl@0: CPPUNIT_ASSERT( *it == (float)i ); sl@0: } sl@0: } sl@0: sl@0: { sl@0: vector*> src(10); sl@0: vector*> dst(src.begin(), src.end()); sl@0: } sl@0: sl@0: { sl@0: derived d; sl@0: //base *pb = &d; sl@0: derived *pd = &d; sl@0: //base **ppb = &pd; sl@0: vector src(10, pd); sl@0: vector dst(src.begin(), src.end()); sl@0: vector::iterator it(dst.begin()), end(dst.end()); sl@0: for (; it != end; ++it) { sl@0: CPPUNIT_ASSERT( (*it) == pd ); sl@0: } sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: { sl@0: //Vector initialization: sl@0: vector vect(10); sl@0: //Just 1 constructor call for the default value: sl@0: CPPUNIT_ASSERT( TrivialInitStruct::nbConstructorCalls == 1 ); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: void UninitializedTest::fill_test() sl@0: { sl@0: } sl@0: sl@0: void UninitializedTest::fill_n_test() sl@0: { sl@0: } sl@0: */