void vector_assign_functor( vector_expression<V, cpu_tag>& v, vector_expression<E, cpu_tag> const& e, F f, sparse_tag tag, dense_tag ){ typedef typename V::value_type value_type; typedef typename V::size_type size_type; value_type zero = value_type(); size_type size = e().size(); typename V::iterator it = v().begin(); for(size_type i = 0; i != size; ++i,++it){ if(it == v().end() || it.index() != i){//insert missing elements it = v().set_element(it,i,zero); } *it = f(*it, e()(i)); } }
void assign( vector_expression<V>& v, vector_expression<E> const& e, F f, sparse_bidirectional_iterator_tag tag, dense_random_access_iterator_tag ) { typedef typename V::value_type value_type; typedef typename V::size_type size_type; value_type zero = value_type(); size_type size = e().size(); typename V::iterator it = v().begin(); for(size_type i = 0; i != size; ++i,++it) { if(it == v().end() || it.index() != i) { //insert missing elements it = v().set_element(it,i,zero); } f(*it, e()(i)); } }
void assign_sparse( vector_expression<V>& v, vector_expression<E> const& e, F f ) { typedef typename V::value_type value_type; typedef typename V::size_type size_type; value_type zero = value_type(); size_type size = v().size(); typename V::iterator it = v().begin(); typename E::const_iterator ite = e().begin(); typename E::const_iterator ite_end = e().end(); while(it != v().end() && ite != ite_end) { size_type it_index = it.index(); size_type ite_index = ite.index(); if (it_index == ite_index) { f(*it, *ite); ++ ite; } else if (it_index < ite_index) { f(*it, zero); } else { //it_index > ite_index so insert new element in v() it = v().set_element(it,ite_index,zero); f(*it, *ite); ++ite; } ++it; } //apply zero transformation on elements which are not transformed yet for(; it != v().end(); ++it) { f(*it, zero); } //add missing elements for(; ite != ite_end; ++it,++ite) { it = v().set_element(it,ite.index(),zero); f(*it, *ite); } }
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() ); }
static typename V::size_type index (const typename V::iterator &i) { return i.index (); }
BOOST_UBLAS_INLINE static typename V::size_type index (const typename V::iterator &i) { return i.index (); }
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 }