Реализация мета-функции zip в c ++ 11

На самом деле я пытаюсь понять, смогу ли я получить минимальную библиотеку, поддерживающую очень немногие операции, которые я использовать из boost :: fusion.

Вот что у меня есть на данный момент ...

template < typename... Types >
struct typelist
{
};

template < template < typename... > class F, typename... Args >
struct apply
{
  typedef typename F < Args... >::type type;
};

template < typename, template < typename... > class >
struct foreach;

template < typename... Types, template < typename Arg > class F >
struct foreach < typelist < Types... >, F >
{
  typedef typelist < typename apply < F, Types >::type... > type; 
};

Поскольку реализация мета-функции foreach тривиальна, я подумал, что zip тоже будет проще. Судя по всему, дело обстоит не так.

template < typename... >
struct zip;

template < typename...  Types0, typename... Types1 >
struct zip < typelist < Types0... >, typelist < Types1... > >
{
  typedef typelist < typelist < Types0, Types1 >... > type;
};

Как я могу обобщить эту zip мета-функцию на произвольное количество списков типов? Кажется, что нам здесь нужен пакет параметров из пакетов параметров.Я не знаю, как это сделать.

Редактировать 1:

Реализация is_equal ...

template < std::size_t... Nn >
struct is_equal;

template < std::size_t N0, std::size_t N1, std::size_t... Nn >
struct is_equal < N0, N1, Nn... >
: and_ <
    typename is_equal < N0, N1 >::type
  , typename is_equal < N1, Nn... >::type
  >::type
{
};

template < std::size_t M, std::size_t N >
struct is_equal < M, N > : std::false_type
{
  typedef std::false_type type;
};

template < std::size_t N >
struct is_equal < N, N > : std::true_type
{
  typedef std::true_type type;
};

Аналогичный подход можно применить и к zip , я думаю ... не пробовал с zip пока нет, но сделаю это, когда я вернусь домой.

Редактировать 2:

Вот то, что я, наконец, подумал, выглядит более элегантно. По сути, это вариант подхода Вона Катона.

namespace impl
{

template < typename Initial, template < typename, typename > class F, typename... Types >
struct foldl;

template < typename Initial, template < typename, typename > class F, typename First, typename... Rest >
struct foldl < Initial, F, First, Rest... >
{
  typedef typename foldl < typename F < Initial, First >::type, F, Rest... >::type type;
};

template < typename Final, template < typename, typename > class F >
struct foldl < Final, F >
{
  typedef Final type;
};

template < typename Type, typename TypeList >
struct cons;

template < typename Type, typename... Types >
struct cons < Type, typelist < Types... > >
{
  typedef typelist < Types..., Type > type;
};

template < typename, typename >
struct zip_accumulator;

template < typename... Types0, typename... Types1 >
struct zip_accumulator < typelist < Types0... >, typelist < Types1... > >
{
  typedef typelist < typename cons < Types1, Types0 >::type... > type;
};

template < typename... Types0 >
struct zip_accumulator < typelist <>, typelist < Types0... > >
{
  typedef typelist < typelist < Types0 >... > type;
};

template < typename... TypeLists >
struct zip
{
  typedef typename foldl < typelist <>, zip_accumulator, TypeLists... >::type type;
};

}

template < typename... TypeLists >
struct zip
{
  static_assert(and_ < typename is_type_list < TypeLists >... >::value, "All parameters must be type lists for zip");
  static_assert(is_equal < TypeLists::length... >::value, "Length of all parameter type lists must be same for zip");
  typedef typename impl::zip < TypeLists... >::type type;
};

template < typename... TypeLists >
struct zip < typelist < TypeLists... > > : zip < TypeLists... >
{
};

Это обрабатывает zip как операцию сворачивания .

16
задан zrb 28 September 2011 в 16:39
поделиться