void TestResizeAndCopy() { typedef tbb::concurrent_vector<Foo> vector_t; for( int old_size=0; old_size<=128; NextSize( old_size ) ) { for( int new_size=old_size; new_size<=128; NextSize( new_size ) ) { long count = FooCount; vector_t v; ASSERT( count==FooCount, NULL ); v.grow_by(old_size); ASSERT( count+old_size==FooCount, NULL ); for( int j=0; j<old_size; ++j ) v[j].bar() = j*j; v.grow_to_at_least(new_size); ASSERT( count+new_size==FooCount, NULL ); for( int j=0; j<new_size; ++j ) { int expected = j<old_size ? j*j : Foo::initial_value_of_bar; if( v[j].bar()!=expected ) std::printf("ERROR on line %d for old_size=%ld new_size=%ld v[%ld].bar()=%d != %d\n",__LINE__,long(old_size),long(new_size),long(j),v[j].bar(), expected); } ASSERT( v.size()==size_t(new_size), NULL ); for( int j=0; j<new_size; ++j ) { v[j].bar() = ~j; } const vector_t& cv = v; // Try copy constructor vector_t copy_of_v(cv); CheckVector(cv,new_size,old_size); v.clear(); ASSERT( v.empty(), NULL ); CheckVector(copy_of_v,new_size,old_size); } } }
//! Test of assign, grow, copying with various sizes void TestResizeAndCopy() { typedef static_counting_allocator<debug_allocator<Foo,std::allocator>, std::size_t> allocator_t; typedef tbb::concurrent_vector<Foo, allocator_t> vector_t; allocator_t::init_counters(); for( int old_size=0; old_size<=128; NextSize( old_size ) ) { for( int new_size=0; new_size<=1280; NextSize( new_size ) ) { long count = FooCount; vector_t v; ASSERT( count==FooCount, NULL ); v.assign(old_size/2, Foo() ); ASSERT( count+old_size/2==FooCount, NULL ); for( int j=0; j<old_size/2; ++j ) ASSERT( v[j].state == Foo::CopyInitialized, NULL); v.assign(FooIterator(0), FooIterator(old_size)); v.resize(new_size, Foo(33) ); ASSERT( count+new_size==FooCount, NULL ); for( int j=0; j<new_size; ++j ) { int expected = j<old_size ? j : 33; if( v[j].bar()!=expected ) REPORT("ERROR on line %d for old_size=%ld new_size=%ld v[%ld].bar()=%d != %d\n",__LINE__,long(old_size),long(new_size),long(j),v[j].bar(), expected); } ASSERT( v.size()==size_t(new_size), NULL ); for( int j=0; j<new_size; ++j ) { v[j].bar() = ~j; } const vector_t& cv = v; // Try copy constructor vector_t copy_of_v(cv); CheckVector(cv,new_size,old_size); ASSERT( !(v != copy_of_v), NULL ); v.clear(); ASSERT( v.empty(), NULL ); swap(v, copy_of_v); ASSERT( copy_of_v.empty(), NULL ); CheckVector(v,new_size,old_size); } } ASSERT( allocator_t::items_allocated == allocator_t::items_freed, NULL); ASSERT( allocator_t::allocations == allocator_t::frees, NULL); }
//! Test reserve, compact, capacity void TestCapacity() { typedef static_counting_allocator<debug_allocator<Foo,tbb::cache_aligned_allocator>, std::size_t> allocator_t; typedef tbb::concurrent_vector<Foo, allocator_t> vector_t; allocator_t::init_counters(); for( size_t old_size=0; old_size<=11000; old_size=(old_size<5 ? old_size+1 : 3*old_size) ) { for( size_t new_size=0; new_size<=11000; new_size=(new_size<5 ? new_size+1 : 3*new_size) ) { long count = FooCount; { vector_t v; v.reserve(old_size); ASSERT( v.capacity()>=old_size, NULL ); v.reserve( new_size ); ASSERT( v.capacity()>=old_size, NULL ); ASSERT( v.capacity()>=new_size, NULL ); ASSERT( v.empty(), NULL ); size_t fill_size = 2*new_size; for( size_t i=0; i<fill_size; ++i ) { ASSERT( size_t(FooCount)==count+i, NULL ); #if TBB_DEPRECATED size_t j = v.grow_by(1); #else size_t j = v.grow_by(1) - v.begin(); #endif ASSERT( j==i, NULL ); v[j].bar() = int(~j); } vector_t copy_of_v(v); // should allocate first segment with same size as for shrink_to_fit() if(__TBB_Log2(/*reserved size*/old_size|1) > __TBB_Log2(fill_size|1) ) ASSERT( v.capacity() != copy_of_v.capacity(), NULL ); v.shrink_to_fit(); ASSERT( v.capacity() == copy_of_v.capacity(), NULL ); CheckVector(v, new_size*2, old_size); // check vector correctness ASSERT( v==copy_of_v, NULL ); // TODO: check also segments layout equality } ASSERT( FooCount==count, NULL ); } } ASSERT( allocator_t::items_allocated == allocator_t::items_freed, NULL); ASSERT( allocator_t::allocations == allocator_t::frees, NULL); }