#include <boost/mpl/long.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/minus.hpp> #include <boost/mpl/multiplies.hpp> #include <boost/mpl/divides.hpp> #include <boost/mpl/modulus.hpp> #include <boost/mpl/list.hpp> #include <boost/mpl/begin_end.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/front.hpp> #include <boost/mpl/push_front.hpp> #include <boost/mpl/pop_front.hpp> #include <boost/mpl/next_prior.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/advance.hpp> #include <boost/mpl/distance.hpp> template< class SeqOfSeqFirst, class SeqOfSeqLast, class SeqOfIndexFirst, class SeqOfIndexLast > struct deref_each_product_iterator { typedef typename boost::mpl::push_front< typename deref_each_product_iterator< typename boost::mpl::next<SeqOfSeqFirst>::type, SeqOfSeqLast, typename boost::mpl::next<SeqOfIndexFirst>::type, SeqOfIndexLast >::type, typename boost::mpl::at< typename boost::mpl::deref<SeqOfSeqFirst>::type, typename boost::mpl::deref<SeqOfIndexFirst>::type >::type >::type type ; }; template<class SeqOfSeqLast, class SeqOfIndexLast> struct deref_each_product_iterator< SeqOfSeqLast, SeqOfSeqLast, SeqOfIndexLast, SeqOfIndexLast > { typedef boost::mpl::list0<> type ; }; template<class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index> struct each_product_iterator { typedef SeqOfSeq sequence_of_sequence; typedef SeqOfSize size_sequence; typedef SeqOfBase base_sequence; typedef Index index; }; template<class Sequence> struct each_product_view { }; template< class SeqOfSizeFirst, class SeqOfSizeLast, class SeqOfBaseFirst, class SeqOfBaseLast, class Index > struct make_index_sequence { typedef typename boost::mpl::push_front< typename make_index_sequence< typename boost::mpl::next<SeqOfSizeFirst>::type, SeqOfSizeLast, typename boost::mpl::next<SeqOfBaseFirst>::type, SeqOfBaseLast, Index >::type, typename boost::mpl::modulus< typename boost::mpl::divides< Index, typename boost::mpl::deref<SeqOfBaseFirst>::type >::type, typename boost::mpl::deref<SeqOfSizeFirst>::type >::type >::type type ; }; template<class SeqOfSizeLast, class SeqOfBaseLast, class Index> struct make_index_sequence< SeqOfSizeLast, SeqOfSizeLast, SeqOfBaseLast, SeqOfBaseLast, Index > { typedef boost::mpl::list0<> type ; }; template<class SeqOfSeqFirst, class SeqOfSeqLast> struct make_size_sequence { typedef typename boost::mpl::push_front< typename make_size_sequence< typename boost::mpl::next<SeqOfSeqFirst>::type, SeqOfSeqLast >::type, typename boost::mpl::size< typename boost::mpl::deref<SeqOfSeqFirst>::type >::type >::type type ; }; template<class SeqOfSeqLast> struct make_size_sequence<SeqOfSeqLast, SeqOfSeqLast> { typedef boost::mpl::list0<> type ; }; template<class SeqOfSizeFirst, class SeqOfSizeLast> struct make_base_sequence_sub { typedef typename make_base_sequence_sub< typename boost::mpl::next<SeqOfSizeFirst>::type, SeqOfSizeLast >::type tmp ; typedef typename boost::mpl::push_front< tmp, typename boost::mpl::multiplies< typename boost::mpl::front<tmp>::type, typename boost::mpl::deref<SeqOfSizeFirst>::type >::type >::type type ; }; template<class SeqOfSizeLast> struct make_base_sequence_sub<SeqOfSizeLast, SeqOfSizeLast> { typedef boost::mpl::list<boost::mpl::long_<1> > type ; }; template<class SeqOfSizeFirst, class SeqOfSizeLast> struct make_base_sequence { typedef typename boost::mpl::pop_front< typename make_base_sequence_sub< SeqOfSizeFirst, SeqOfSizeLast >::type >::type type ; }; namespace boost{ namespace mpl{ template<class SeqOfSeq> struct size<each_product_view<SeqOfSeq> > { typedef typename make_size_sequence< typename boost::mpl::begin<SeqOfSeq>::type, typename boost::mpl::end<SeqOfSeq>::type >::type size_sequence ; typedef typename make_base_sequence< typename boost::mpl::begin<size_sequence>::type, typename boost::mpl::end<size_sequence>::type >::type base_sequence ; typedef typename boost::mpl::multiplies< typename boost::mpl::front<size_sequence>::type, typename boost::mpl::front<base_sequence>::type >::type type ; }; template<class SeqOfSeq> struct begin<each_product_view<SeqOfSeq> > { typedef typename make_size_sequence< typename boost::mpl::begin<SeqOfSeq>::type, typename boost::mpl::end<SeqOfSeq>::type >::type size_sequence ; typedef typename make_base_sequence< typename boost::mpl::begin<size_sequence>::type, typename boost::mpl::end<size_sequence>::type >::type base_sequence ; typedef each_product_iterator< SeqOfSeq, size_sequence, base_sequence, boost::mpl::long_<0> > type ; }; template<class SeqOfSeq> struct end<each_product_view<SeqOfSeq> > { typedef typename boost::mpl::size<each_product_view<SeqOfSeq> >::type size ; typedef typename boost::mpl::advance< typename boost::mpl::begin<each_product_view<SeqOfSeq> >::type, size >::type type ; }; template<class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index> struct next<each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index> > { typedef each_product_iterator< SeqOfSeq, SeqOfSize, SeqOfBase, typename boost::mpl::plus<Index, boost::mpl::long_<1> >::type > type ; }; template<class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index> struct prior<each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index> > { typedef each_product_iterator< SeqOfSeq, SeqOfSize, SeqOfBase, typename boost::mpl::plus<Index, boost::mpl::long_<-1> >::type > type ; }; template< class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index, class N > struct advance<each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index>, N> { typedef each_product_iterator< SeqOfSeq, SeqOfSize, SeqOfBase, typename boost::mpl::plus<Index, N>::type > type ; }; template< class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index1, class Index2 > struct distance< each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index1>, each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index2> > { typedef typename boost::mpl::minus<Index2, Index1>::type type ; }; template<class SeqOfSeq, class SeqOfSize, class SeqOfBase, class Index> struct deref<each_product_iterator<SeqOfSeq, SeqOfSize, SeqOfBase, Index> > { typedef typename make_index_sequence< typename boost::mpl::begin<SeqOfSize>::type, typename boost::mpl::end<SeqOfSize>::type, typename boost::mpl::begin<SeqOfBase>::type, typename boost::mpl::end<SeqOfBase>::type, Index >::type index_sequence ; typedef typename deref_each_product_iterator< typename boost::mpl::begin<SeqOfSeq>::type, typename boost::mpl::end<SeqOfSeq>::type, typename boost::mpl::begin<index_sequence>::type, typename boost::mpl::end<index_sequence>::type >::type type ; }; }} // namespace boost::mpl //////////////////// 以上ライブラリコード //////////////////// //////////////////// 以下クライアントコード //////////////////// #include <iostream> #include <typeinfo> template<class First, class Last> struct meta_sequence_printer_impl { static void print() { std::cout << typeid(typename boost::mpl::deref<First>::type).name() << ", "; meta_sequence_printer_impl< typename boost::mpl::next<First>::type, Last >::print(); } }; template<class Last> struct meta_sequence_printer_impl<Last, Last> { static void print() { std::cout << std::endl; } }; template<class Sequence> void print_meta_sequence() { meta_sequence_printer_impl< typename boost::mpl::begin<Sequence>::type, typename boost::mpl::end<Sequence>::type >::print(); } template<class First, class Last> struct print_meta_sequence_of_meta_sequence_impl { static void print() { using namespace boost::mpl; print_meta_sequence<typename deref<First>::type>(); print_meta_sequence_of_meta_sequence_impl< typename next<First>::type, Last >::print(); } }; template<class Last> struct print_meta_sequence_of_meta_sequence_impl<Last, Last> { static void print() { } }; template<class SequenceOfSequence> void print_meta_sequence_of_meta_sequence() { using namespace boost::mpl; print_meta_sequence_of_meta_sequence_impl< typename begin<SequenceOfSequence>::type, typename end<SequenceOfSequence>::type >::print(); } int main() { using namespace boost::mpl; typedef list3< list2<bool, char>, list3<short, int, long>, list2<float, double> > ll ; print_meta_sequence_of_meta_sequence<each_product_view<ll> >(); }
自分の環境ではVC++7.1で前のコードより3倍程度コンパイル速度が速くなった.GCCでも2倍程度速くなった.でも期待したほどの向上じゃなくて(´・ω・`)ショボーン.VC++7.1,GCC3.3.1双方で試したところ,共に2^8 = 256の積生成まで耐えられる模様.
ちなみに,2^9 = 512の積生成を試してみたらコンパイラが音を上げた.特にGCCはコンパイルエラーを吐くだけで12分もかかるという前代未聞の事態がw.