[Home]CPPTM Answers - Exercise 7-2

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

 // (by Ariel Badichi)
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/is_same.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/list_c.hpp>
 #include <boost/mpl/prior.hpp>
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/iterator_category.hpp>
 #include <boost/mpl/contains.hpp>

 namespace mpl = boost::mpl;
 using namespace boost::mpl::placeholders;

 // Seq - sequence of iterator categories
 template<typename Seq>
 struct least_refined_iterator_category
     : mpl::eval_if<
           mpl::contains<Seq, mpl::forward_iterator_tag>,
           mpl::identity<mpl::forward_iterator_tag>,
           mpl::if_<
               mpl::contains<Seq, mpl::bidirectional_iterator_tag>,
               mpl::bidirectional_iterator_tag,
               mpl::random_access_iterator_tag
           >
       >
 {};

 // Seq - sequence of iterators
 template<typename Seq>
 struct iterator_category_view 
     : mpl::transform_view<
           Seq,
           mpl::iterator_category<_>
       >
 {};

 template<typename IteratorSeq?>
 struct zip_iterator
 {
     typedef typename least_refined_iterator_category<
         iterator_category_view<IteratorSeq?>
     >::type 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;
         };

         template<typename IteratorSeq?>
         struct prior< ::zip_iterator<IteratorSeq?> >
         {
             typedef ::zip_iterator<
                 typename transform<
                     IteratorSeq?,
                     prior<_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 zip_view<mpl::vector3<v1, v2, v3> > z1;
     typedef mpl::begin<z1>::type first1;
     BOOST_STATIC_ASSERT((boost::is_same<
                              mpl::iterator_category<first1>::type, 
                              mpl::random_access_iterator_tag
                          >::value));

     typedef mpl::list3_c<int, 6, 6, 6> l1;
     typedef zip_view<mpl::vector<v1, l1, v2> > z2;
     typedef mpl::begin<z2>::type first2;
     BOOST_STATIC_ASSERT((boost::is_same<
                              mpl::iterator_category<first2>::type, 
                              mpl::forward_iterator_tag
                          >::value));
 }

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited March 27, 2005 11:55 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers