void TestSequentialFor() { V v; v.grow_by(N); // Check iterator tbb::tick_count t0 = tbb::tick_count::now(); typename V::iterator p = v.begin(); ASSERT( !(*p).is_const(), NULL ); ASSERT( !p->is_const(), NULL ); for( int i=0; size_t(i)<v.size(); ++i, ++p ) { if( (*p).state!=Foo::DefaultInitialized ) std::printf("ERROR for v[%ld]\n", long(i)); typename V::reference pref = *p; pref.bar() = i; typename V::difference_type delta = p-v.begin(); ASSERT( delta==i, NULL ); ASSERT( -delta<=0, "difference type not signed?" ); } tbb::tick_count t1 = tbb::tick_count::now(); // Check const_iterator going forwards const V& u = v; typename V::const_iterator cp = u.begin(); ASSERT( (*cp).is_const(), NULL ); ASSERT( cp->is_const(), NULL ); for( int i=0; size_t(i)<u.size(); ++i, ++cp ) { CheckConstIterator(u,i,cp); } tbb::tick_count t2 = tbb::tick_count::now(); if( Verbose ) std::printf("Time for serial for: assign time = %8.5f, check time = %8.5f\n", (t1-t0).seconds(),(t2-t1).seconds()); // Now go backwards cp = u.end(); for( int i=int(u.size()); i>0; ) { --i; --cp; if( i>0 ) { typename V::const_iterator cp_old = cp--; int here = (*cp_old).bar(); ASSERT( here==u[i].bar(), NULL ); typename V::const_iterator cp_new = cp++; int prev = (*cp_new).bar(); ASSERT( prev==u[i-1].bar(), NULL ); } CheckConstIterator(u,i,cp); } // Now go forwards and backwards cp = u.begin(); ptrdiff_t k = 0; for( size_t i=0; i<u.size(); ++i ) { CheckConstIterator(u,int(k),cp); typename V::difference_type delta = i*3 % u.size(); if( 0<=k+delta && size_t(k+delta)<u.size() ) { cp += delta; k += delta; } delta = i*7 % u.size(); if( 0<=k-delta && size_t(k-delta)<u.size() ) { if( i&1 ) cp -= delta; // Test operator-= else cp = cp - delta; // Test operator- k -= delta; } } for( int i=0; size_t(i)<u.size(); i=(i<50?i+1:i*3) ) for( int j=-i; size_t(i+j)<u.size(); j=(j<50?j+1:j*5) ) { ASSERT( (u.begin()+i)[j].bar()==i+j, NULL ); ASSERT( (v.begin()+i)[j].bar()==i+j, NULL ); ASSERT( (i+u.begin())[j].bar()==i+j, NULL ); ASSERT( (i+v.begin())[j].bar()==i+j, NULL ); } CheckIteratorComparison<typename V::iterator, typename V::iterator>(v); CheckIteratorComparison<typename V::iterator, typename V::const_iterator>(v); CheckIteratorComparison<typename V::const_iterator, typename V::iterator>(v); CheckIteratorComparison<typename V::const_iterator, typename V::const_iterator>(v); TestIteratorAssignment<typename V::const_iterator>( u.begin() ); TestIteratorAssignment<typename V::const_iterator>( v.begin() ); TestIteratorAssignment<typename V::iterator>( v.begin() ); // Check reverse_iterator typename V::reverse_iterator rp = v.rbegin(); for( size_t i=v.size(); i>0; --i, ++rp ) { typename V::reference pref = *rp; ASSERT( size_t(pref.bar())==i-1, NULL ); ASSERT( rp!=v.rend(), NULL ); } ASSERT( rp==v.rend(), NULL ); // Check const_reverse_iterator typename V::const_reverse_iterator crp = u.rbegin(); for( size_t i=v.size(); i>0; --i, ++crp ) { typename V::const_reference cpref = *crp; ASSERT( size_t(cpref.bar())==i-1, NULL ); ASSERT( crp!=u.rend(), NULL ); } ASSERT( crp==u.rend(), NULL ); TestIteratorAssignment<typename V::const_reverse_iterator>( u.rbegin() ); TestIteratorAssignment<typename V::reverse_iterator>( v.rbegin() ); }
void TestSequentialFor() { typedef tbb::concurrent_vector<FooWithAssign> V; V v(N); ASSERT(v.grow_by(0) == v.grow_by(0, FooWithAssign()), NULL); // Check iterator tbb::tick_count t0 = tbb::tick_count::now(); typename V::iterator p = v.begin(); ASSERT( !(*p).is_const(), NULL ); ASSERT( !p->is_const(), NULL ); for( int i=0; size_t(i)<v.size(); ++i, ++p ) { if( (*p).state!=Foo::DefaultInitialized ) REPORT("ERROR for v[%ld]\n", long(i)); typename V::reference pref = *p; pref.bar() = i; typename V::difference_type delta = p-v.begin(); ASSERT( delta==i, NULL ); ASSERT( -delta<=0, "difference type not signed?" ); } tbb::tick_count t1 = tbb::tick_count::now(); // Check const_iterator going forwards const V& u = v; typename V::const_iterator cp = u.begin(); ASSERT( cp == v.cbegin(), NULL ); ASSERT( (*cp).is_const(), NULL ); ASSERT( cp->is_const(), NULL ); ASSERT( *cp == v.front(), NULL); for( int i=0; size_t(i)<u.size(); ++i ) { CheckConstIterator(u,i,cp); V::const_iterator &cpr = ++cp; ASSERT( &cpr == &cp, "preincrement not returning a reference?"); } tbb::tick_count t2 = tbb::tick_count::now(); REMARK("Time for serial for: assign time = %8.5f, check time = %8.5f\n", (t1-t0).seconds(),(t2-t1).seconds()); // Now go backwards cp = u.end(); ASSERT( cp == v.cend(), NULL ); for( int i=int(u.size()); i>0; ) { --i; V::const_iterator &cpr = --cp; ASSERT( &cpr == &cp, "predecrement not returning a reference?"); if( i>0 ) { typename V::const_iterator cp_old = cp--; int here = (*cp_old).bar(); ASSERT( here==u[i].bar(), NULL ); typename V::const_iterator cp_new = cp++; int prev = (*cp_new).bar(); ASSERT( prev==u[i-1].bar(), NULL ); } CheckConstIterator(u,i,cp); } // Now go forwards and backwards ptrdiff_t k = 0; cp = u.begin(); for( size_t i=0; i<u.size(); ++i ) { CheckConstIterator(u,int(k),cp); typename V::difference_type delta = i*3 % u.size(); if( 0<=k+delta && size_t(k+delta)<u.size() ) { V::const_iterator &cpr = (cp += delta); ASSERT( &cpr == &cp, "+= not returning a reference?"); k += delta; } delta = i*7 % u.size(); if( 0<=k-delta && size_t(k-delta)<u.size() ) { if( i&1 ) { V::const_iterator &cpr = (cp -= delta); ASSERT( &cpr == &cp, "-= not returning a reference?"); } else cp = cp - delta; // Test operator- k -= delta; } } for( int i=0; size_t(i)<u.size(); i=(i<50?i+1:i*3) ) for( int j=-i; size_t(i+j)<u.size(); j=(j<50?j+1:j*5) ) { ASSERT( (u.begin()+i)[j].bar()==i+j, NULL ); ASSERT( (v.begin()+i)[j].bar()==i+j, NULL ); ASSERT((v.cbegin()+i)[j].bar()==i+j, NULL ); ASSERT( (i+u.begin())[j].bar()==i+j, NULL ); ASSERT( (i+v.begin())[j].bar()==i+j, NULL ); ASSERT((i+v.cbegin())[j].bar()==i+j, NULL ); } CheckIteratorComparison<typename V::iterator, typename V::iterator>(v); CheckIteratorComparison<typename V::iterator, typename V::const_iterator>(v); CheckIteratorComparison<typename V::const_iterator, typename V::iterator>(v); CheckIteratorComparison<typename V::const_iterator, typename V::const_iterator>(v); TestIteratorAssignment<typename V::const_iterator>( u.begin() ); TestIteratorAssignment<typename V::const_iterator>( v.begin() ); TestIteratorAssignment<typename V::const_iterator>( v.cbegin() ); TestIteratorAssignment<typename V::iterator>( v.begin() ); // doesn't compile as expected: TestIteratorAssignment<typename V::iterator>( u.begin() ); TestRangeAssignment<typename V::const_range_type>( u.range() ); TestRangeAssignment<typename V::const_range_type>( v.range() ); TestRangeAssignment<typename V::range_type>( v.range() ); // doesn't compile as expected: TestRangeAssignment<typename V::range_type>( u.range() ); // Check reverse_iterator typename V::reverse_iterator rp = v.rbegin(); for( size_t i=v.size(); i>0; --i, ++rp ) { typename V::reference pref = *rp; ASSERT( size_t(pref.bar())==i-1, NULL ); ASSERT( rp!=v.rend(), NULL ); } ASSERT( rp==v.rend(), NULL ); // Check const_reverse_iterator typename V::const_reverse_iterator crp = u.rbegin(); ASSERT( crp == v.crbegin(), NULL ); ASSERT( *crp == v.back(), NULL); for( size_t i=v.size(); i>0; --i, ++crp ) { typename V::const_reference cpref = *crp; ASSERT( size_t(cpref.bar())==i-1, NULL ); ASSERT( crp!=u.rend(), NULL ); } ASSERT( crp == u.rend(), NULL ); ASSERT( crp == v.crend(), NULL ); TestIteratorAssignment<typename V::const_reverse_iterator>( u.rbegin() ); TestIteratorAssignment<typename V::reverse_iterator>( v.rbegin() ); // test compliance with C++ Standard 2003, clause 23.1.1p9 { tbb::concurrent_vector<int> v1, v2(1, 100); v1.assign(1, 100); ASSERT(v1 == v2, NULL); ASSERT(v1.size() == 1 && v1[0] == 100, "used integral iterators"); } // cross-allocator tests #if !defined(_WIN64) || defined(_CPPLIB_VER) typedef local_counting_allocator<std::allocator<int>, size_t> allocator1_t; typedef tbb::cache_aligned_allocator<void> allocator2_t; typedef tbb::concurrent_vector<FooWithAssign, allocator1_t> V1; typedef tbb::concurrent_vector<FooWithAssign, allocator2_t> V2; V1 v1( v ); // checking cross-allocator copying V2 v2( 10 ); v2 = v1; // checking cross-allocator assignment ASSERT( (v1 == v) && !(v2 != v), NULL); ASSERT( !(v1 < v) && !(v2 > v), NULL); ASSERT( (v1 <= v) && (v2 >= v), NULL); #endif }