First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 //Has to be first for StackAllocator swap overload to be taken
17 //into account (at least using GCC 4.0.1)
18 #include "stack_allocator.h"
23 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
27 #include "cppunit/cppunit_proxy.h"
29 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
36 class VectorTest : public CPPUNIT_NS::TestCase
38 CPPUNIT_TEST_SUITE(VectorTest);
39 CPPUNIT_TEST(vec_test_1);
40 CPPUNIT_TEST(vec_test_2);
41 CPPUNIT_TEST(vec_test_3);
42 CPPUNIT_TEST(vec_test_4);
43 CPPUNIT_TEST(vec_test_5);
44 CPPUNIT_TEST(vec_test_6);
45 CPPUNIT_TEST(vec_test_7);
46 CPPUNIT_TEST(capacity);
48 CPPUNIT_TEST(pointer);
49 CPPUNIT_TEST(auto_ref);
50 CPPUNIT_TEST(allocator_with_state);
51 CPPUNIT_TEST(iterators);
52 #if defined (STLPORT) && defined (_STLP_NO_MEMBER_TEMPLATES)
55 CPPUNIT_TEST(optimizations_check);
58 CPPUNIT_TEST(vec_cov1);
59 CPPUNIT_TEST(vec_cov2);
60 CPPUNIT_TEST(vec_cov3);
61 CPPUNIT_TEST(vec_cov4);
62 CPPUNIT_TEST_SUITE_END();
76 void allocator_with_state();
78 void optimizations_check();
86 CPPUNIT_TEST_SUITE_REGISTRATION(VectorTest);
89 // tests implementation
91 void VectorTest::vec_test_1()
93 vector<int> v1; // Empty vector of integers.
95 CPPUNIT_ASSERT( v1.empty() == true );
96 CPPUNIT_ASSERT( v1.size() == 0 );
98 // CPPUNIT_ASSERT( v1.max_size() == INT_MAX / sizeof(int) );
99 // cout << "max_size = " << v1.max_size() << endl;
100 v1.push_back(42); // Add an integer to the vector.
102 CPPUNIT_ASSERT( v1.size() == 1 );
104 CPPUNIT_ASSERT( v1[0] == 42 );
107 vector<vector<int> > vect(10);
108 vector<vector<int> >::iterator it(vect.begin()), end(vect.end());
109 for (; it != end; ++it) {
110 CPPUNIT_ASSERT( (*it).empty() );
111 CPPUNIT_ASSERT( (*it).size() == 0 );
112 CPPUNIT_ASSERT( (*it).capacity() == 0 );
113 CPPUNIT_ASSERT( (*it).begin() == (*it).end() );
118 void VectorTest::vec_test_2()
120 vector<double> v1; // Empty vector of doubles.
123 vector<double> v2; // Another empty vector of doubles.
126 CPPUNIT_ASSERT( v1.size() == 2 );
127 CPPUNIT_ASSERT( v1[0] == 32.1 );
128 CPPUNIT_ASSERT( v1[1] == 40.5 );
130 CPPUNIT_ASSERT( v2.size() == 1 );
131 CPPUNIT_ASSERT( v2[0] == 3.56 );
132 v1.swap(v2); // Swap the vector's contents.
134 CPPUNIT_ASSERT( v1.size() == 1 );
135 CPPUNIT_ASSERT( v1[0] == 3.56 );
137 CPPUNIT_ASSERT( v2.size() == 2 );
138 CPPUNIT_ASSERT( v2[0] == 32.1 );
139 CPPUNIT_ASSERT( v2[1] == 40.5 );
141 v2 = v1; // Assign one vector to another.
143 CPPUNIT_ASSERT( v2.size() == 1 );
144 CPPUNIT_ASSERT( v2[0] == 3.56 );
147 void VectorTest::vec_test_3()
149 typedef vector<char> vec_type;
151 vec_type v1; // Empty vector of characters.
155 CPPUNIT_ASSERT( v1.size() == 2 );
156 CPPUNIT_ASSERT( v1[0] == 'h' );
157 CPPUNIT_ASSERT( v1[1] == 'i' );
159 vec_type v2(v1.begin(), v1.end());
160 v2[1] = 'o'; // Replace second character.
162 CPPUNIT_ASSERT( v2.size() == 2 );
163 CPPUNIT_ASSERT( v2[0] == 'h' );
164 CPPUNIT_ASSERT( v2[1] == 'o' );
166 CPPUNIT_ASSERT( (v1 == v2) == false );
168 CPPUNIT_ASSERT( (v1 < v2) == true );
171 void VectorTest::vec_test_4()
180 CPPUNIT_ASSERT( v.front() == 1 );
181 CPPUNIT_ASSERT( v.back() == 16 );
185 CPPUNIT_ASSERT( v.back() == 25 );
186 CPPUNIT_ASSERT( v.size() == 5 );
190 CPPUNIT_ASSERT( v.back() == 16 );
191 CPPUNIT_ASSERT( v.size() == 4 );
194 void VectorTest::vec_test_5()
196 int array [] = { 1, 4, 9, 16 };
198 vector<int> v(array, array + 4);
200 CPPUNIT_ASSERT( v.size() == 4 );
202 CPPUNIT_ASSERT( v[0] == 1 );
203 CPPUNIT_ASSERT( v[1] == 4 );
204 CPPUNIT_ASSERT( v[2] == 9 );
205 CPPUNIT_ASSERT( v[3] == 16 );
208 void VectorTest::vec_test_6()
210 int array [] = { 1, 4, 9, 16, 25, 36 };
212 vector<int> v(array, array + 6);
213 vector<int>::iterator vit;
215 CPPUNIT_ASSERT( v.size() == 6 );
216 CPPUNIT_ASSERT( v[0] == 1 );
217 CPPUNIT_ASSERT( v[1] == 4 );
218 CPPUNIT_ASSERT( v[2] == 9 );
219 CPPUNIT_ASSERT( v[3] == 16 );
220 CPPUNIT_ASSERT( v[4] == 25 );
221 CPPUNIT_ASSERT( v[5] == 36 );
223 vit = v.erase( v.begin() ); // Erase first element.
224 CPPUNIT_ASSERT( *vit == 4 );
226 CPPUNIT_ASSERT( v.size() == 5 );
227 CPPUNIT_ASSERT( v[0] == 4 );
228 CPPUNIT_ASSERT( v[1] == 9 );
229 CPPUNIT_ASSERT( v[2] == 16 );
230 CPPUNIT_ASSERT( v[3] == 25 );
231 CPPUNIT_ASSERT( v[4] == 36 );
233 vit = v.erase(v.end() - 1); // Erase last element.
234 CPPUNIT_ASSERT( vit == v.end() );
236 CPPUNIT_ASSERT( v.size() == 4 );
237 CPPUNIT_ASSERT( v[0] == 4 );
238 CPPUNIT_ASSERT( v[1] == 9 );
239 CPPUNIT_ASSERT( v[2] == 16 );
240 CPPUNIT_ASSERT( v[3] == 25 );
243 v.erase(v.begin() + 1, v.end() - 1); // Erase all but first and last.
245 CPPUNIT_ASSERT( v.size() == 2 );
246 CPPUNIT_ASSERT( v[0] == 4 );
247 CPPUNIT_ASSERT( v[1] == 25 );
251 void VectorTest::vec_test_7()
253 int array1 [] = { 1, 4, 25 };
254 int array2 [] = { 9, 16 };
256 vector<int> v(array1, array1 + 3);
257 vector<int>::iterator vit;
258 vit = v.insert(v.begin(), 0); // Insert before first element.
259 CPPUNIT_ASSERT( *vit == 0 );
261 vit = v.insert(v.end(), 36); // Insert after last element.
262 CPPUNIT_ASSERT( *vit == 36 );
264 CPPUNIT_ASSERT( v.size() == 5 );
265 CPPUNIT_ASSERT( v[0] == 0 );
266 CPPUNIT_ASSERT( v[1] == 1 );
267 CPPUNIT_ASSERT( v[2] == 4 );
268 CPPUNIT_ASSERT( v[3] == 25 );
269 CPPUNIT_ASSERT( v[4] == 36 );
271 // Insert contents of array2 before fourth element.
272 v.insert(v.begin() + 3, array2, array2 + 2);
274 CPPUNIT_ASSERT( v.size() == 7 );
276 CPPUNIT_ASSERT( v[0] == 0 );
277 CPPUNIT_ASSERT( v[1] == 1 );
278 CPPUNIT_ASSERT( v[2] == 4 );
279 CPPUNIT_ASSERT( v[3] == 9 );
280 CPPUNIT_ASSERT( v[4] == 16 );
281 CPPUNIT_ASSERT( v[5] == 25 );
282 CPPUNIT_ASSERT( v[6] == 36 );
285 CPPUNIT_ASSERT( v.empty() );
287 v.insert(v.begin(), 5, 10);
288 CPPUNIT_ASSERT( v.size() == 5 );
289 CPPUNIT_ASSERT( v[0] == 10 );
290 CPPUNIT_ASSERT( v[1] == 10 );
291 CPPUNIT_ASSERT( v[2] == 10 );
292 CPPUNIT_ASSERT( v[3] == 10 );
293 CPPUNIT_ASSERT( v[4] == 10 );
297 vector<float> vf(2.0f, 3.0f);
298 CPPUNIT_ASSERT( vf.size() == 2 );
299 CPPUNIT_ASSERT( vf.front() == 3.0f );
300 CPPUNIT_ASSERT( vf.back() == 3.0f );
310 void VectorTest::capacity()
315 CPPUNIT_ASSERT( v.capacity() == 0 );
317 CPPUNIT_ASSERT( v.capacity() >= 1 );
319 CPPUNIT_ASSERT( v.capacity() >= 5000 );
323 //Test that used to generate an assertion when using __debug_alloc.
324 vector<TestStruct> va;
330 void VectorTest::at() {
332 vector<int> const& cv = v;
335 CPPUNIT_ASSERT( v.at(0) == 10 );
337 CPPUNIT_ASSERT( cv.at(0) == 20 );
339 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
343 CPPUNIT_ASSERT(false);
345 catch (out_of_range const&) {
349 CPPUNIT_ASSERT(false);
355 void VectorTest::pointer()
358 vector<int *> v2 = v1;
361 v3.insert( v3.end(), v1.begin(), v1.end() );
364 void VectorTest::auto_ref()
367 for (int i = 0; i < 5; ++i) {
371 vector<vector<int> > v_v_int(1, ref);
372 v_v_int.push_back(v_v_int[0]);
373 v_v_int.push_back(ref);
374 v_v_int.push_back(v_v_int[0]);
375 v_v_int.push_back(v_v_int[0]);
376 v_v_int.push_back(ref);
378 vector<vector<int> >::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end());
379 for (; vvit != vvitEnd; ++vvit) {
380 CPPUNIT_ASSERT( *vvit == ref );
384 * Forbidden by the Standard:
385 v_v_int.insert(v_v_int.end(), v_v_int.begin(), v_v_int.end());
386 for (vvit = v_v_int.begin(), vvitEnd = v_v_int.end();
387 vvit != vvitEnd; ++vvit) {
388 CPPUNIT_ASSERT( *vvit == ref );
393 void VectorTest::allocator_with_state()
396 StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
399 StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
402 typedef vector<int, StackAllocator<int> > VectorInt;
403 VectorInt vint1(10, 0, stack1);
404 VectorInt vint1Cpy(vint1);
406 VectorInt vint2(10, 1, stack2);
407 VectorInt vint2Cpy(vint2);
411 CPPUNIT_ASSERT( vint1.get_allocator().swaped() );
412 CPPUNIT_ASSERT( vint2.get_allocator().swaped() );
414 CPPUNIT_ASSERT( vint1 == vint2Cpy );
415 CPPUNIT_ASSERT( vint2 == vint1Cpy );
416 CPPUNIT_ASSERT( vint1.get_allocator() == stack2 );
417 CPPUNIT_ASSERT( vint2.get_allocator() == stack1 );
419 CPPUNIT_ASSERT( stack1.ok() );
420 CPPUNIT_ASSERT( stack2.ok() );
427 struct PointEx : public Point {
428 PointEx() : builtFromBase(false) {}
429 PointEx(const Point&) : builtFromBase(true) {}
434 #if defined (STLPORT)
437 struct __type_traits<PointEx> {
438 typedef __false_type has_trivial_default_constructor;
439 typedef __true_type has_trivial_copy_constructor;
440 typedef __true_type has_trivial_assignment_operator;
441 typedef __true_type has_trivial_destructor;
442 typedef __true_type is_POD_type;
447 //This test check that vector implementation do not over optimize
448 //operation as PointEx copy constructor is trivial
449 void VectorTest::optimizations_check()
451 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
453 CPPUNIT_ASSERT( v1.size() == 1 );
455 vector<PointEx> v2(v1.begin(), v1.end());
456 CPPUNIT_ASSERT( v2.size() == 1 );
457 CPPUNIT_ASSERT( v2[0].builtFromBase == true );
461 void VectorTest::iterators()
463 vector<int> vint(10, 0);
464 vector<int> const& crvint = vint;
466 CPPUNIT_ASSERT( vint.begin() == vint.begin() );
467 CPPUNIT_ASSERT( crvint.begin() == vint.begin() );
468 CPPUNIT_ASSERT( vint.begin() == crvint.begin() );
469 CPPUNIT_ASSERT( crvint.begin() == crvint.begin() );
471 CPPUNIT_ASSERT( vint.begin() != vint.end() );
472 CPPUNIT_ASSERT( crvint.begin() != vint.end() );
473 CPPUNIT_ASSERT( vint.begin() != crvint.end() );
474 CPPUNIT_ASSERT( crvint.begin() != crvint.end() );
476 CPPUNIT_ASSERT( vint.rbegin() == vint.rbegin() );
478 //CPPUNIT_ASSERT( vint.rbegin() == crvint.rbegin() );
479 //CPPUNIT_ASSERT( crvint.rbegin() == vint.rbegin() );
480 CPPUNIT_ASSERT( crvint.rbegin() == crvint.rbegin() );
482 CPPUNIT_ASSERT( vint.rbegin() != vint.rend() );
484 //CPPUNIT_ASSERT( vint.rbegin() != crvint.rend() );
485 //CPPUNIT_ASSERT( crvint.rbegin() != vint.rend() );
486 CPPUNIT_ASSERT( crvint.rbegin() != crvint.rend() );
489 #if defined (STLPORT)
490 # define NOTHROW _STLP_NOTHROW
492 # define NOTHROW throw()
495 /* This allocator implementation purpose is simply to break some
496 * internal STLport mecanism specific to the STLport own allocator
499 struct NotSTLportAllocator : public allocator<_Tp> {
500 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATE_CLASSES)
501 template <class _Tp1> struct rebind {
502 typedef NotSTLportAllocator<_Tp1> other;
505 NotSTLportAllocator() _STLP_NOTHROW {}
506 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES)
507 template <class _Tp1> NotSTLportAllocator(const NotSTLportAllocator<_Tp1>&) NOTHROW {}
509 NotSTLportAllocator(const NotSTLportAllocator<_Tp>&) NOTHROW {}
510 ~NotSTLportAllocator() NOTHROW {}
513 /* This test check a potential issue with empty base class
514 * optimization. Some compilers (VC6) do not implement it
515 * correctly resulting ina wrong behavior. */
516 void VectorTest::ebo()
518 // We use heap memory as test failure can corrupt vector internal
519 // representation making executable crash on vector destructor invocation.
520 // We prefer a simple memory leak, internal corruption should be reveal
521 // by size or capacity checks.
522 typedef vector<int, NotSTLportAllocator<int> > V;
523 V *pv1 = new V(1, 1);
524 V *pv2 = new V(10, 2);
526 size_t v1Capacity = pv1->capacity();
527 size_t v2Capacity = pv2->capacity();
531 CPPUNIT_ASSERT( pv1->size() == 10 );
532 CPPUNIT_ASSERT( pv1->capacity() == v2Capacity );
533 CPPUNIT_ASSERT( (*pv1)[5] == 2 );
535 CPPUNIT_ASSERT( pv2->size() == 1 );
536 CPPUNIT_ASSERT( pv2->capacity() == v1Capacity );
537 CPPUNIT_ASSERT( (*pv2)[0] == 1 );
542 void VectorTest::vec_cov1()
547 vector<int> const& cv = v;
553 CPPUNIT_ASSERT( cv.front() == 10 );
554 CPPUNIT_ASSERT( cv.back() == 50 );
559 for (i = 1 ; i < 6 ; ++i )
561 vec.push_back ( 3 * i );
563 vector <int>::reverse_iterator rVPOS1 = vec.rend ( ) - 1;
565 CPPUNIT_ASSERT( *rVPOS1 == 9 );
566 vector <int>::reverse_iterator rVPOS2 =rVPOS1 + 2;
567 CPPUNIT_ASSERT( *rVPOS2 == 3 );
572 for (i = 1 ; i < 6 ; ++i )
574 vec.push_back ( 2 * i );
576 vector <int>::reverse_iterator rVPOS1 = vec.rbegin ( );
578 CPPUNIT_ASSERT( *rVPOS1 == 6 );
582 void VectorTest::vec_cov2()
588 for (i = 1 ; i < 6 ; ++i )
590 vec.push_back ( 2 * i - 1 );
592 vector <int>::reverse_iterator rVPOS1 = vec.rend ( ) - 1;
594 CPPUNIT_ASSERT( *rVPOS1 == 3 );
599 for (i = 1 ; i < 6 ; ++i )
601 vec.push_back ( 2 * i );
603 vector <int>::iterator pos;
604 pos = find ( vec.begin ( ), vec.end ( ), 8 );
605 reverse_iterator<vector<int>::iterator> rpos ( pos );
606 reverse_iterator<vector<int>::iterator>::difference_type diff = 2;
607 reverse_iterator<vector<int>::iterator>::reference refrpos = rpos [diff];
608 CPPUNIT_ASSERT( refrpos == 2 );
613 for ( i = 1 ; i < 6 ; ++i )
617 vector <int>::iterator pos;
618 pos = find ( vec.begin ( ), vec.end ( ), 4 );
619 vector <int>::reverse_iterator rpos ( pos );
620 CPPUNIT_ASSERT( *rpos == 3 );
624 void VectorTest::vec_cov3()
630 for (i = 1 ; i < 3 ; ++i )
632 vec.push_back ( 10 * i );
634 back_insert_iterator<vector<int> > backiter ( vec );
639 vector <int>::iterator vIter;
640 vIter = vec.begin ( ) ;
641 CPPUNIT_ASSERT( *vIter == 10 );
643 CPPUNIT_ASSERT( *vIter == 20 );
645 CPPUNIT_ASSERT( *vIter == 30 );
647 CPPUNIT_ASSERT( *vIter == 40 );
652 insert_iterator<vector<int> > ii ( vec, vec.begin ( ) );
654 vector <int>::iterator vIter;
655 vIter = vec.begin ( ) ;
656 CPPUNIT_ASSERT( *vIter == 30 );
661 for (i = 1 ; i < 6 ; ++i )
663 vec.push_back ( 3 * i );
665 vector <int>::reverse_iterator rVPOS1 = vec.rend ( ) - 1;
666 vector <int>::reverse_iterator rVPOS2 = vec.rbegin ( );
667 CPPUNIT_ASSERT(*rVPOS2 > *rVPOS1);
672 void VectorTest::vec_cov4()
683 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
687 CPPUNIT_ASSERT(false);
689 catch (length_error const&) {
693 CPPUNIT_ASSERT(false);