mpl::for_each にループカウンタを付ける

mpl::zip_view と mpl::range_c を使えば、割と簡単に実装出来ました。


[ソース]

#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/zip_view.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <iostream>

namespace mpl = boost::mpl;

typedef mpl::vector_c<int, 3, 6, 2, 1, 4, 0, 5> seq;

struct disp{
    template<typename T>
    void operator()(T) const{
        std::cout 
            << mpl::at_c<T, 1>::type::value
            << ":"
            << mpl::at_c<T, 0>::type::value
            << std::endl;
    }
};

int
main(){
    mpl::for_each<
        mpl::zip_view<
            mpl::vector<
                seq,
                mpl::range_c<int, 0, mpl::size<seq>::value>
            >
        >
    >(disp());
    
    return 0;
}

[出力]

0:3
1:6
2:2
3:1
4:4
5:0
6:5


このままだとちょっと分かりづらいので、軽くラッピング。
[ソース]

#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/zip_view.hpp>
#include <boost/mpl/unpack_args.hpp>


template<typename T, typename Index>
struct with_index_impl{
    typedef T type;
    typedef Index index;
};

template<typename T, typename Index>
struct with_index
    : boost::mpl::identity<with_index_impl<T, Index> >{};

template<
    typename Sequence,
    typename TransformOp,
    typename F
>
void for_each_with_index(F f, Sequence* =0, TransformOp* =0){
    namespace mpl = boost::mpl;
    mpl::for_each<
        mpl::transform_view<
            mpl::zip_view<
                mpl::vector<
                    Sequence,
                    mpl::range_c<int, 0, mpl::size<Sequence>::value>
                >
            >,
            mpl::unpack_args<with_index<mpl::_1, mpl::_2> >
        >,
        TransformOp
    >(f);
}

template<
    typename Sequence,
    typename F
>
void for_each_with_index(F f, Sequence* =0){
    for_each_with_index<Sequence, boost::mpl::identity<> >(f);
}


#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/print.hpp>
#include <iostream>

namespace mpl = boost::mpl;

typedef mpl::vector_c<int, 3, 6, 2, 1, 4, 0, 5> seq;

struct disp{
    template<typename T>
    void operator()(T) const{
        std::cout
            << T::index::value << ":" << T::type::value <<
        std::endl;
    }
};

int
main(){
    for_each_with_index<seq>(disp());
    return 0;
}

これで、だいぶ楽になったかな。


[追記]
TransformOp に対応していなかったので、ちょっと修正。

[boost]
ver 1.46.1