Adaptor that provides a flattened view of a container of containers.
template<typename Container> class flattened2; template <typename Container> flattened2d<Container> flatten2d(const Container &c); template <typename Container> flattened2d<Container> flatten2d( const Container &c, const typename Container::const_iterator b, const typename Container::const_iterator e);
#include "tbb/enumerable_thread_specific.h"
A flattened2d provides a flattened view of a container of containers. Iterating from begin() to end()visits all of the elements in the inner containers. This can be useful when traversing an enumerable_thread_specific whose elements are containers.
The utility function flatten2d creates a flattened2d object from a container.
The following code shows a simple example usage of flatten2d and flattened2d. Each thread collects the values of i that are evenly divisible by K in a thread-local vector. In main, the results are printed by using a flattened2d to simplify the traversal of all of the elements in all of the local vectors.
#include <iostream> #include <utility> #include <vector> #include "tbb/task_scheduler_init.h" #include "tbb/enumerable_thread_specific.h" #include "tbb/parallel_for.h" #include "tbb/blocked_range.h" using namespace tbb; // A VecType has a separate std::vector<int> per thread typedef enumerable_thread_specific< std::vector<int> > VecType; VecType MyVectors; int K = 1000000; struct Func { void operator()(const blocked_range<int>& r) const { VecType::reference v = MyVectors.local(); for (int i=r.begin(); i!=r.end(); ++i) if( i%k==0 ) v.push_back(i); } }; int main() { parallel_for(blocked_range<int>(0, 100000000), Func()); flattened2d<VecType> flat_view = flatten2d( MyVectors ); for( flattened2d<VecType>::const_iterator i = flat_view.begin(); i != flat_view.end(); ++i) cout << *i << endl; return 0; }
namespace tbb { template<typename Container> class flattened2d { public: // Basic types typedef implementation-dependent size_type; typedef implementation-dependent difference_type; typedef implementation-dependent allocator_type; typedef implementation-dependent value_type; typedef implementation-dependent reference; typedef implementation-dependent const_reference; typedef implementation-dependent pointer; typedef implementation-dependent const_pointer; typedef implementation-dependent iterator; typedef implementation-dependent const_iterator; flattened2d( const Container& c ); flattened2d( const Container& c, typename Container::const_iterator first, typename Container::const_iterator last ); iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; size_type size() const; }; template <typename Container> flattened2d<Container> flatten2d(const Container &c); template <typename Container> flattened2d<Container> flatten2d( const Container &c, const typename Container::const_iterator first, const typename Container::const_iterator last); }