ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

vector_test.cpp
Go to the documentation of this file.
00001 //Has to be first for StackAllocator swap overload to be taken
00002 //into account (at least using GCC 4.0.1)
00003 #include "stack_allocator.h"
00004 
00005 #include <vector>
00006 #include <algorithm>
00007 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
00008 # include <stdexcept>
00009 #endif
00010 
00011 #include "cppunit/cppunit_proxy.h"
00012 
00013 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
00014 using namespace std;
00015 #endif
00016 
00017 //
00018 // TestCase class
00019 //
00020 class VectorTest : public CPPUNIT_NS::TestCase
00021 {
00022   CPPUNIT_TEST_SUITE(VectorTest);
00023   CPPUNIT_TEST(vec_test_1);
00024   CPPUNIT_TEST(vec_test_2);
00025   CPPUNIT_TEST(vec_test_3);
00026   CPPUNIT_TEST(vec_test_4);
00027   CPPUNIT_TEST(vec_test_5);
00028   CPPUNIT_TEST(vec_test_6);
00029   CPPUNIT_TEST(vec_test_7);
00030   CPPUNIT_TEST(capacity);
00031   CPPUNIT_TEST(at);
00032   CPPUNIT_TEST(pointer);
00033   CPPUNIT_TEST(auto_ref);
00034   CPPUNIT_TEST(allocator_with_state);
00035   CPPUNIT_TEST(iterators);
00036 #if defined (STLPORT) && defined (_STLP_NO_MEMBER_TEMPLATES)
00037   CPPUNIT_IGNORE;
00038 #endif
00039   CPPUNIT_TEST(optimizations_check);
00040   CPPUNIT_TEST(assign_check);
00041   CPPUNIT_STOP_IGNORE;
00042   CPPUNIT_TEST(ebo);
00043   CPPUNIT_TEST_SUITE_END();
00044 
00045 protected:
00046   void vec_test_1();
00047   void vec_test_2();
00048   void vec_test_3();
00049   void vec_test_4();
00050   void vec_test_5();
00051   void vec_test_6();
00052   void vec_test_7();
00053   void capacity();
00054   void at();
00055   void pointer();
00056   void auto_ref();
00057   void allocator_with_state();
00058   void iterators();
00059   void optimizations_check();
00060   void assign_check();
00061   void ebo();
00062 };
00063 
00064 CPPUNIT_TEST_SUITE_REGISTRATION(VectorTest);
00065 
00066 //
00067 // tests implementation
00068 //
00069 void VectorTest::vec_test_1()
00070 {
00071   vector<int> v1; // Empty vector of integers.
00072 
00073   CPPUNIT_ASSERT( v1.empty() == true );
00074   CPPUNIT_ASSERT( v1.size() == 0 );
00075 
00076   // CPPUNIT_ASSERT( v1.max_size() == INT_MAX / sizeof(int) );
00077   // cout << "max_size = " << v1.max_size() << endl;
00078   v1.push_back(42); // Add an integer to the vector.
00079 
00080   CPPUNIT_ASSERT( v1.size() == 1 );
00081 
00082   CPPUNIT_ASSERT( v1[0] == 42 );
00083 
00084   {
00085     vector<vector<int> > vect(10);
00086     vector<vector<int> >::iterator it(vect.begin()), end(vect.end());
00087     for (; it != end; ++it) {
00088       CPPUNIT_ASSERT( (*it).empty() );
00089       CPPUNIT_ASSERT( (*it).size() == 0 );
00090       CPPUNIT_ASSERT( (*it).capacity() == 0 );
00091       CPPUNIT_ASSERT( (*it).begin() == (*it).end() );
00092     }
00093   }
00094 }
00095 
00096 void VectorTest::vec_test_2()
00097 {
00098   vector<double> v1; // Empty vector of doubles.
00099   v1.push_back(32.1);
00100   v1.push_back(40.5);
00101   vector<double> v2; // Another empty vector of doubles.
00102   v2.push_back(3.56);
00103 
00104   CPPUNIT_ASSERT( v1.size() == 2 );
00105   CPPUNIT_ASSERT( v1[0] == 32.1 );
00106   CPPUNIT_ASSERT( v1[1] == 40.5 );
00107 
00108   CPPUNIT_ASSERT( v2.size() == 1 );
00109   CPPUNIT_ASSERT( v2[0] == 3.56 );
00110   size_t v1Cap = v1.capacity();
00111   size_t v2Cap = v2.capacity();
00112 
00113   v1.swap(v2); // Swap the vector's contents.
00114 
00115   CPPUNIT_ASSERT( v1.size() == 1 );
00116   CPPUNIT_ASSERT( v1.capacity() == v2Cap );
00117   CPPUNIT_ASSERT( v1[0] == 3.56 );
00118 
00119   CPPUNIT_ASSERT( v2.size() == 2 );
00120   CPPUNIT_ASSERT( v2.capacity() == v1Cap );
00121   CPPUNIT_ASSERT( v2[0] == 32.1 );
00122   CPPUNIT_ASSERT( v2[1] == 40.5 );
00123 
00124   v2 = v1; // Assign one vector to another.
00125 
00126   CPPUNIT_ASSERT( v2.size() == 1 );
00127   CPPUNIT_ASSERT( v2[0] == 3.56 );
00128 }
00129 
00130 void VectorTest::vec_test_3()
00131 {
00132   typedef vector<char> vec_type;
00133 
00134   vec_type v1; // Empty vector of characters.
00135   v1.push_back('h');
00136   v1.push_back('i');
00137 
00138   CPPUNIT_ASSERT( v1.size() == 2 );
00139   CPPUNIT_ASSERT( v1[0] == 'h' );
00140   CPPUNIT_ASSERT( v1[1] == 'i' );
00141 
00142   vec_type v2(v1.begin(), v1.end());
00143   v2[1] = 'o'; // Replace second character.
00144 
00145   CPPUNIT_ASSERT( v2.size() == 2 );
00146   CPPUNIT_ASSERT( v2[0] == 'h' );
00147   CPPUNIT_ASSERT( v2[1] == 'o' );
00148 
00149   CPPUNIT_ASSERT( (v1 == v2) == false );
00150 
00151   CPPUNIT_ASSERT( (v1 < v2) == true );
00152 }
00153 
00154 void VectorTest::vec_test_4()
00155 {
00156   vector<int> v(4);
00157 
00158   v[0] = 1;
00159   v[1] = 4;
00160   v[2] = 9;
00161   v[3] = 16;
00162 
00163   CPPUNIT_ASSERT( v.front() == 1 );
00164   CPPUNIT_ASSERT( v.back() == 16 );
00165 
00166   v.push_back(25);
00167 
00168   CPPUNIT_ASSERT( v.back() == 25 );
00169   CPPUNIT_ASSERT( v.size() == 5 );
00170 
00171   v.pop_back();
00172 
00173   CPPUNIT_ASSERT( v.back() == 16 );
00174   CPPUNIT_ASSERT( v.size() == 4 );
00175 }
00176 
00177 void VectorTest::vec_test_5()
00178 {
00179   int array [] = { 1, 4, 9, 16 };
00180 
00181   vector<int> v(array, array + 4);
00182 
00183   CPPUNIT_ASSERT( v.size() == 4 );
00184 
00185   CPPUNIT_ASSERT( v[0] == 1 );
00186   CPPUNIT_ASSERT( v[1] == 4 );
00187   CPPUNIT_ASSERT( v[2] == 9 );
00188   CPPUNIT_ASSERT( v[3] == 16 );
00189 }
00190 
00191 void VectorTest::vec_test_6()
00192 {
00193   int array [] = { 1, 4, 9, 16, 25, 36 };
00194 
00195   vector<int> v(array, array + 6);
00196   vector<int>::iterator vit;
00197 
00198   CPPUNIT_ASSERT( v.size() == 6 );
00199   CPPUNIT_ASSERT( v[0] == 1 );
00200   CPPUNIT_ASSERT( v[1] == 4 );
00201   CPPUNIT_ASSERT( v[2] == 9 );
00202   CPPUNIT_ASSERT( v[3] == 16 );
00203   CPPUNIT_ASSERT( v[4] == 25 );
00204   CPPUNIT_ASSERT( v[5] == 36 );
00205 
00206   vit = v.erase( v.begin() ); // Erase first element.
00207   CPPUNIT_ASSERT( *vit == 4 );
00208 
00209   CPPUNIT_ASSERT( v.size() == 5 );
00210   CPPUNIT_ASSERT( v[0] == 4 );
00211   CPPUNIT_ASSERT( v[1] == 9 );
00212   CPPUNIT_ASSERT( v[2] == 16 );
00213   CPPUNIT_ASSERT( v[3] == 25 );
00214   CPPUNIT_ASSERT( v[4] == 36 );
00215 
00216   vit = v.erase(v.end() - 1); // Erase last element.
00217   CPPUNIT_ASSERT( vit == v.end() );
00218 
00219   CPPUNIT_ASSERT( v.size() == 4 );
00220   CPPUNIT_ASSERT( v[0] == 4 );
00221   CPPUNIT_ASSERT( v[1] == 9 );
00222   CPPUNIT_ASSERT( v[2] == 16 );
00223   CPPUNIT_ASSERT( v[3] == 25 );
00224 
00225 
00226   v.erase(v.begin() + 1, v.end() - 1); // Erase all but first and last.
00227 
00228   CPPUNIT_ASSERT( v.size() == 2 );
00229   CPPUNIT_ASSERT( v[0] == 4 );
00230   CPPUNIT_ASSERT( v[1] == 25 );
00231 
00232 }
00233 
00234 void VectorTest::vec_test_7()
00235 {
00236   int array1 [] = { 1, 4, 25 };
00237   int array2 [] = { 9, 16 };
00238 
00239   vector<int> v(array1, array1 + 3);
00240   vector<int>::iterator vit;
00241   vit = v.insert(v.begin(), 0); // Insert before first element.
00242   CPPUNIT_ASSERT( *vit == 0 );
00243 
00244   vit = v.insert(v.end(), 36);  // Insert after last element.
00245   CPPUNIT_ASSERT( *vit == 36 );
00246 
00247   CPPUNIT_ASSERT( v.size() == 5 );
00248   CPPUNIT_ASSERT( v[0] == 0 );
00249   CPPUNIT_ASSERT( v[1] == 1 );
00250   CPPUNIT_ASSERT( v[2] == 4 );
00251   CPPUNIT_ASSERT( v[3] == 25 );
00252   CPPUNIT_ASSERT( v[4] == 36 );
00253 
00254   // Insert contents of array2 before fourth element.
00255   v.insert(v.begin() + 3, array2, array2 + 2);
00256 
00257   CPPUNIT_ASSERT( v.size() == 7 );
00258 
00259   CPPUNIT_ASSERT( v[0] == 0 );
00260   CPPUNIT_ASSERT( v[1] == 1 );
00261   CPPUNIT_ASSERT( v[2] == 4 );
00262   CPPUNIT_ASSERT( v[3] == 9 );
00263   CPPUNIT_ASSERT( v[4] == 16 );
00264   CPPUNIT_ASSERT( v[5] == 25 );
00265   CPPUNIT_ASSERT( v[6] == 36 );
00266 
00267   v.clear();
00268   CPPUNIT_ASSERT( v.empty() );
00269 
00270   v.insert(v.begin(), 5, 10);
00271   CPPUNIT_ASSERT( v.size() == 5 );
00272   CPPUNIT_ASSERT( v[0] == 10 );
00273   CPPUNIT_ASSERT( v[1] == 10 );
00274   CPPUNIT_ASSERT( v[2] == 10 );
00275   CPPUNIT_ASSERT( v[3] == 10 );
00276   CPPUNIT_ASSERT( v[4] == 10 );
00277 
00278   /*
00279   {
00280     vector<float> vf(2.0f, 3.0f);
00281     CPPUNIT_ASSERT( vf.size() == 2 );
00282     CPPUNIT_ASSERT( vf.front() == 3.0f );
00283     CPPUNIT_ASSERT( vf.back() == 3.0f );
00284   }
00285   */
00286 }
00287 
00288 struct TestStruct
00289 {
00290   unsigned int a[3];
00291 };
00292 
00293 void VectorTest::capacity()
00294 {
00295   {
00296     vector<int> v;
00297 
00298     CPPUNIT_ASSERT( v.capacity() == 0 );
00299     v.push_back(42);
00300     CPPUNIT_ASSERT( v.capacity() >= 1 );
00301     v.reserve(5000);
00302     CPPUNIT_ASSERT( v.capacity() >= 5000 );
00303   }
00304 
00305   {
00306     //Test that used to generate an assertion when using __debug_alloc.
00307     vector<TestStruct> va;
00308     va.reserve(1);
00309     va.reserve(2);
00310   }
00311 }
00312 
00313 void VectorTest::at() {
00314   vector<int> v;
00315   vector<int> const& cv = v;
00316 
00317   v.push_back(10);
00318   CPPUNIT_ASSERT( v.at(0) == 10 );
00319   v.at(0) = 20;
00320   CPPUNIT_ASSERT( cv.at(0) == 20 );
00321 
00322 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
00323   try {
00324     v.at(1) = 20;
00325     CPPUNIT_FAIL;
00326   }
00327   catch (out_of_range const&) {
00328   }
00329   catch (...) {
00330     CPPUNIT_FAIL;
00331   }
00332 #endif
00333 }
00334 
00335 void VectorTest::pointer()
00336 {
00337   vector<int *> v1;
00338   vector<int *> v2 = v1;
00339   vector<int *> v3;
00340 
00341   v3.insert( v3.end(), v1.begin(), v1.end() );
00342 }
00343 
00344 void VectorTest::auto_ref()
00345 {
00346   vector<int> ref;
00347   for (int i = 0; i < 5; ++i) {
00348     ref.push_back(i);
00349   }
00350 
00351   vector<vector<int> > v_v_int(1, ref);
00352   v_v_int.push_back(v_v_int[0]);
00353   v_v_int.push_back(ref);
00354   v_v_int.push_back(v_v_int[0]);
00355   v_v_int.push_back(v_v_int[0]);
00356   v_v_int.push_back(ref);
00357 
00358   vector<vector<int> >::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end());
00359   for (; vvit != vvitEnd; ++vvit) {
00360     CPPUNIT_ASSERT( *vvit == ref );
00361   }
00362 
00363   /*
00364    * Forbidden by the Standard:
00365   v_v_int.insert(v_v_int.end(), v_v_int.begin(), v_v_int.end());
00366   for (vvit = v_v_int.begin(), vvitEnd = v_v_int.end();
00367        vvit != vvitEnd; ++vvit) {
00368     CPPUNIT_ASSERT( *vvit == ref );
00369   }
00370    */
00371 }
00372 
00373 void VectorTest::allocator_with_state()
00374   {
00375     char buf1[1024];
00376     StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
00377 
00378     char buf2[1024];
00379     StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
00380 
00381     {
00382       typedef vector<int, StackAllocator<int> > VectorInt;
00383       VectorInt vint1(10, 0, stack1);
00384       VectorInt vint1Cpy(vint1);
00385 
00386       VectorInt vint2(10, 1, stack2);
00387       VectorInt vint2Cpy(vint2);
00388 
00389       vint1.swap(vint2);
00390 
00391       CPPUNIT_ASSERT( vint1.get_allocator().swaped() );
00392       CPPUNIT_ASSERT( vint2.get_allocator().swaped() );
00393 
00394       CPPUNIT_ASSERT( vint1 == vint2Cpy );
00395       CPPUNIT_ASSERT( vint2 == vint1Cpy );
00396       CPPUNIT_ASSERT( vint1.get_allocator() == stack2 );
00397       CPPUNIT_ASSERT( vint2.get_allocator() == stack1 );
00398     }
00399     CPPUNIT_ASSERT( stack1.ok() );
00400     CPPUNIT_ASSERT( stack2.ok() );
00401   }
00402 
00403 struct Point {
00404   int x, y;
00405 };
00406 
00407 struct PointEx : public Point {
00408   PointEx() : builtFromBase(false) {}
00409   PointEx(const Point&) : builtFromBase(true) {}
00410 
00411   bool builtFromBase;
00412 };
00413 
00414 #if defined (STLPORT)
00415 #  if defined (_STLP_USE_NAMESPACES)
00416 namespace std {
00417 #  endif
00418   _STLP_TEMPLATE_NULL
00419   struct __type_traits<PointEx> {
00420     typedef __false_type has_trivial_default_constructor;
00421     typedef __true_type has_trivial_copy_constructor;
00422     typedef __true_type has_trivial_assignment_operator;
00423     typedef __true_type has_trivial_destructor;
00424     typedef __true_type is_POD_type;
00425   };
00426 #  if defined (_STLP_USE_NAMESPACES)
00427 }
00428 #  endif
00429 #endif
00430 
00431 //This test check that vector implementation do not over optimize
00432 //operation as PointEx copy constructor is trivial
00433 void VectorTest::optimizations_check()
00434 {
00435 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
00436   vector<Point> v1(1);
00437   CPPUNIT_ASSERT( v1.size() == 1 );
00438 
00439   vector<PointEx> v2(v1.begin(), v1.end());
00440   CPPUNIT_ASSERT( v2.size() == 1 );
00441   CPPUNIT_ASSERT( v2[0].builtFromBase == true );
00442 #endif
00443 }
00444 
00445 void VectorTest::assign_check()
00446 {
00447 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
00448   vector<int> v(3,1);
00449   int array[] = { 1, 2, 3, 4, 5 };
00450   
00451   v.assign( array, array + 5 );
00452   CPPUNIT_CHECK( v[4] == 5 );
00453   CPPUNIT_CHECK( v[0] == 1 );
00454   CPPUNIT_CHECK( v[1] == 2 );
00455 #endif
00456 }
00457 
00458 void VectorTest::iterators()
00459 {
00460   vector<int> vint(10, 0);
00461   vector<int> const& crvint = vint;
00462 
00463   CPPUNIT_ASSERT( vint.begin() == vint.begin() );
00464   CPPUNIT_ASSERT( crvint.begin() == vint.begin() );
00465   CPPUNIT_ASSERT( vint.begin() == crvint.begin() );
00466   CPPUNIT_ASSERT( crvint.begin() == crvint.begin() );
00467 
00468   CPPUNIT_ASSERT( vint.begin() != vint.end() );
00469   CPPUNIT_ASSERT( crvint.begin() != vint.end() );
00470   CPPUNIT_ASSERT( vint.begin() != crvint.end() );
00471   CPPUNIT_ASSERT( crvint.begin() != crvint.end() );
00472 
00473   CPPUNIT_ASSERT( vint.rbegin() == vint.rbegin() );
00474   // Not Standard:
00475   //CPPUNIT_ASSERT( vint.rbegin() == crvint.rbegin() );
00476   //CPPUNIT_ASSERT( crvint.rbegin() == vint.rbegin() );
00477   CPPUNIT_ASSERT( crvint.rbegin() == crvint.rbegin() );
00478 
00479   CPPUNIT_ASSERT( vint.rbegin() != vint.rend() );
00480   // Not Standard:
00481   //CPPUNIT_ASSERT( vint.rbegin() != crvint.rend() );
00482   //CPPUNIT_ASSERT( crvint.rbegin() != vint.rend() );
00483   CPPUNIT_ASSERT( crvint.rbegin() != crvint.rend() );
00484 }
00485 
00486 
00487 #if !defined (STLPORT) || \
00488     !defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00489 /* Simple compilation test: Check that nested types like iterator
00490  * can be access even if type used to instanciate container is not
00491  * yet completely defined.
00492  */
00493 class IncompleteClass
00494 {
00495   vector<IncompleteClass> instances;
00496   typedef vector<IncompleteClass>::iterator it;
00497 };
00498 #endif
00499 
00500 #if defined (STLPORT)
00501 #  define NOTHROW _STLP_NOTHROW
00502 #else
00503 #  define NOTHROW throw()
00504 #endif
00505 
00506 /* This allocator implementation purpose is simply to break some
00507  * internal STLport mecanism specific to the STLport own allocator
00508  * implementation. */
00509 template <class _Tp>
00510 struct NotSTLportAllocator : public allocator<_Tp> {
00511 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00512   template <class _Tp1> struct rebind {
00513     typedef NotSTLportAllocator<_Tp1> other;
00514   };
00515 #endif
00516   NotSTLportAllocator() NOTHROW {}
00517 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES)
00518   template <class _Tp1> NotSTLportAllocator(const NotSTLportAllocator<_Tp1>&) NOTHROW {}
00519 #endif
00520   NotSTLportAllocator(const NotSTLportAllocator<_Tp>&) NOTHROW {}
00521   ~NotSTLportAllocator() NOTHROW {}
00522 };
00523 
00524 /* This test check a potential issue with empty base class
00525  * optimization. Some compilers (VC6) do not implement it
00526  * correctly resulting ina wrong behavior. */
00527 void VectorTest::ebo()
00528 {
00529   // We use heap memory as test failure can corrupt vector internal
00530   // representation making executable crash on vector destructor invocation.
00531   // We prefer a simple memory leak, internal corruption should be reveal
00532   // by size or capacity checks.
00533   typedef vector<int, NotSTLportAllocator<int> > V;
00534   V *pv1 = new V(1, 1);
00535   V *pv2 = new V(10, 2);
00536 
00537   size_t v1Capacity = pv1->capacity();
00538   size_t v2Capacity = pv2->capacity();
00539 
00540   pv1->swap(*pv2);
00541 
00542   CPPUNIT_ASSERT( pv1->size() == 10 );
00543   CPPUNIT_ASSERT( pv1->capacity() == v2Capacity );
00544   CPPUNIT_ASSERT( (*pv1)[5] == 2 );
00545 
00546   CPPUNIT_ASSERT( pv2->size() == 1 );
00547   CPPUNIT_ASSERT( pv2->capacity() == v1Capacity );
00548   CPPUNIT_ASSERT( (*pv2)[0] == 1 );
00549 
00550   delete pv2;
00551   delete pv1;
00552 }
00553 

Generated on Mon May 28 2012 04:35:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.