直積生成 in Boost.MPL

Boost.PreprocessorにあるBOOST_PP_SEQ_EACH_PRODUCTのTemplate MeataProgramming版.
#っていうかBOOST_PP_SEQ_EACH_PRODUCTなんて無いし.BOOST_PP_SEQ_FOR_EACH_PRODUCTでした.っていうかこのTMP版も生成した直積を陽にシーケンスで返すんじゃなくて,各直積についてメタ関数を呼び出す形にしたほうが圧倒的に効率的ですにゃ.

#include <boost/mpl/list.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/joint_view.hpp>

template<class T, class First, class Last>
struct each_product_sub2
{
  typedef
    typename boost::mpl::push_front<
      typename each_product_sub2<
        T,
        typename boost::mpl::next<First>::type,
        Last
      >::type,
      typename boost::mpl::push_front<
        typename boost::mpl::deref<First>::type,
        T
      >::type
    >::type
    type
    ;
};

template<class T, class Last>
struct each_product_sub2<T, Last, Last>
{
  typedef
    boost::mpl::list0<>
    type
    ;
};

template<class First1, class Last1, class First2, class Last2>
struct each_product_sub1
{
  typedef
    typename boost::mpl::joint_view<
      typename each_product_sub1<
        typename boost::mpl::next<First1>::type,
        Last1,
        First2,
        Last2
      >::type,
      typename each_product_sub2<
        typename boost::mpl::deref<First1>::type,
        First2,
        Last2
      >::type
    >::type
    type
    ;
};

template<class Last1, class First2, class Last2>
struct each_product_sub1<Last1, Last1, First2, Last2>
{
  typedef
    boost::mpl::list0<>
    type
    ;
};

template<class First, class Last>
struct each_product
{
  typedef
    typename boost::mpl::deref<First>::type
    front
    ;
  typedef
    typename each_product<
      typename boost::mpl::next<First>::type,
      Last
    >::type
    result
    ;
  typedef
    typename each_product_sub1<
      typename boost::mpl::begin<front>::type,
      typename boost::mpl::end<front>::type,
      typename boost::mpl::begin<result>::type,
      typename boost::mpl::end<result>::type
    >::type
    type
    ;
};

template<class Last>
struct each_product<Last, Last>
{
  typedef
    boost::mpl::list1<boost::mpl::list0<> >
    type
    ;
};


////////////////////  以上,ライブラリコード  ////////////////////
//////////////////// 以下,クライアントコード ////////////////////


typedef
  boost::mpl::list3<
    boost::mpl::list2<char, wchar_t>,
    boost::mpl::list2<char, wchar_t>,
    boost::mpl::list2<char, wchar_t>
  >
  ll
  ;

// 各直積を要素とするシーケンス
// list<
//   list<wchar_t, wchar_t, wchar_t>,
//   list<wchar_t, wchat_t, char>,
//   list<wchar_t, char, wchar_t>,
//   list<wchar_t, char, char>,
//   list<char, wchar_t, wchar_t>,
//   list<char, wchat_t, char>,
//   list<char, char, wchar_t>,
//   list<char, char, char>
// >
// を作成.
typedef
  each_product<
    boost::mpl::begin<ll>::type,
    boost::mpl::end<ll>::type
  >::type
  result
  ;

#include <iostream>

// 以下,表示用のクラステンプレート群
//
// クラステンプレート + static関数は
// 関数の部分特殊化をエミュレートするための常套手段
template<class First, class Last>
struct mpl_sequence_printer
{
  static void print()
  {
    std::cout
      << typeid(typename boost::mpl::deref<First>::type).name()
      << ", "
      ;
    mpl_sequence_printer<typename boost::mpl::next<First>::type, Last>::print();
  }
};

template<class Last>
struct mpl_sequence_printer<Last, Last>
{
  static void print()
  { }
};

template<class First, class Last>
struct mpl_sequence_of_sequence_printer
{
  static void print()
  {
    mpl_sequence_printer<
      typename boost::mpl::begin<
        typename boost::mpl::deref<First>::type
      >::type,
      typename boost::mpl::end<
        typename boost::mpl::deref<First>::type
      >::type
    >::print();
    std::cout << '\n';
    mpl_sequence_of_sequence_printer<
      typename boost::mpl::next<First>::type,
      Last
    >::print();
  }
};

template<class Last>
struct mpl_sequence_of_sequence_printer<Last, Last>
{
  static void print()
  { }
};

int main()
{
  mpl_sequence_of_sequence_printer<
    boost::mpl::begin<result>::type,
    boost::mpl::end<result>::type
  >::print();
}

相も変わらず何の役に立つのか自分にも見当が付かないという・・・.
(´-`).。oO(いや,本当に見当が付いてないなら作らないんですが・・・)
ちなみに言うまでもないことですが,組み合わせで効いてくるのでちょっと生成元のシーケンスをでかくしただけですぐにコンパイラが悲鳴を上げます.一応,ある程度効率を考慮してlist + push_frontにしてますが・・・もっと高効率の書き方があるんだろうなぁ・・・(っていうかあるでしょう.MPLはどうもコードの効率が予測できない).
ちなみに,うちの超ヘボマシーン + VC++でも2^7 = 128の直積生成はコンパイルが通りました.・・・main関数がたった4行しかないコードのコンパイルに10分という時間が費やされましたけれどね.('Д')y ─┛~~
#そういえばTMPのコードを効率化する方法としてアンローリングかけるとかいうのをちらほら聴くなぁ.試してみたら面白いかも.アンローリングなんて言葉,行列積書いて遊んでた時以来だ・・・まさか,再度お目にかかるとはorz.