Reputation: 61479
I have two arrays, as follows:
std::array<int,6> A,B;
//Fill A with random data
//File B with random data
For whatever reason, I'd like some kind of container object which lets me access both of the vectors individually, but also to iterate over their union, allowing for actions such as follows:
union_container uc(A,B);
for(unioned::iterator i=uc.begin();i!=uc.end();++i)
*i+=1;
uc.first()[2]=4;
uc.second()[4]=5;
I could code this unioned class myself, but perhaps there is already a library which allows this?
Upvotes: 1
Views: 398
Reputation: 70556
Using Boost zip iterators is one way to do this.
#include <array>
#include <functional>
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
template<typename T>
using ZipIt = boost::zip_iterator< boost::tuple<T*, T*> >;
template<typename T>
using ZipRef = decltype(*ZipIt<T>());
template<typename T>
void operator+=(ZipRef<T> z, T const& v)
{
z.template get<0>() += v;
z.template get<1>() += v;
}
int main()
{
std::array<int, 6> a = { 1, 3, 5, 7, 9, 11 };
std::array<int, 6> b = { 2, 4, 6, 8, 10, 12 };
std::for_each(
boost::make_zip_iterator(boost::make_tuple(std::begin(a), std::begin(b))),
boost::make_zip_iterator(boost::make_tuple(std::end(a), std::end(b))),
[](ZipRef<int> z){ z += 1; }
);
std::copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
std::copy(std::begin(b), std::end(b), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
a[2] = 4;
b[4] = 5;
}
Online output.
Note that the code above is not as general as I've would liked, since the jump to variadic templates and general iterator types proved a bit hairy (left as an exercise!) This has mainly to do with the fact that boost::zip_iterator
uses some tricky internal facades around boost::tuple
. For this reason I also used decltype
in the template alias for ZipRef
to avoid having to write such nasty types inside the std::for_each
lambda expression.
Upvotes: 1