// (by Ariel Badichi) #include <boost/static_assert.hpp> #include <boost/mpl/iterator_tags.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/next.hpp> #include <boost/mpl/iterator_range.hpp> #include <boost/mpl/begin.hpp> #include <boost/mpl/end.hpp> #include <boost/mpl/transform_view.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/unpack_args.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/equal.hpp>
namespace mpl = boost::mpl; using namespace boost::mpl::placeholders;
template<typename IteratorSeq?> struct zip_iterator { typedef mpl::forward_iterator_tag category;
typedef IteratorSeq? base;
typedef typename mpl::transform< IteratorSeq?, mpl::deref<_1> >::type type; };
namespace boost { namespace mpl { template<typename IteratorSeq?> struct next< ::zip_iterator<IteratorSeq?> > { typedef ::zip_iterator< typename transform< IteratorSeq?, next<_1> >::type > type; }; } }
// I use mpl::transform instead of mpl::transform_view written in the book.
template<typename Sequences> struct zip_view : mpl::iterator_range< zip_iterator< typename mpl::transform< Sequences, mpl::begin<_1> >::type >, zip_iterator< typename mpl::transform< Sequences, mpl::end<_1> >::type > > { };
int main() { typedef mpl::vector3_c<int, 1, 2, 3> v1; typedef mpl::vector3_c<int, 4, 5, 6> v2; typedef mpl::vector3_c<int, 7, 8, 9> v3; typedef mpl::vector3<v1, v2, v3> vecs;
typedef mpl::transform_view< zip_view<vecs>, mpl::unpack_args<mpl::plus<_, _, _> > > view;
typedef mpl::vector_c<int, 12, 15, 18> expected; BOOST_STATIC_ASSERT((mpl::equal<expected, view>::type::value)); }