Loki::Typelist

タイプリストの定義

タイプリストは、以下の2つのクラスを使つて構成できる、型のリストである。

class NullType {};

template <typename H, typename T>
struct Typelist {
  typedef H Head;
  typedef T Tail;
};

タイプリストを作るには、以下の様にする。

typedef Typelist<char,
                 Typelist<unsigned char,
                          Typelist<signed char,
                                   NullType> > > charlist;

これだと面倒臭いし可読性も悪いので、TYPELIST_X マクロが用意されてゐる。

#define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
#define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >
...

このマクロを使ふと、上述の charlist は次の様に書ける。

typedef TYPELIST_3(char, unsigned char, signed char) charlist;

リストの基本的な操作

タイプリストに対して、要素が値である普通のリストと同じ様に、様々な操作を定義することが出来る。

例へば、タイプリストの長さを得るテンプレートクラス Length は次の様にすれば良い。

template <typename List>
struct Length;

template <typename H, typename T>
struct Length<TypeList<H, T> > {
  enum { value = Length<T>::value + 1 };
};

template <>
struct Length<NullType> {
  enum { value = 0 };
};

tlist がタイプリストである時、Length<tlist>::valuetlist の長さを表す。tlist がタイプリストでない時はコンパイルエラーになる。

数値だけでなく、型を得る操作も定義出来る。例へば、N 番目の要素を得るには以下の様にする。

template <typename List, int N>
struct TypeAt;

template <typename H, typename T, int N>
struct TypeAt<TypeList<H, T>, N> {
  typedef typename TypeAt<T, N-1>::Result Result;
};

template <typename H, typename T>
struct TypeAt<TypeList<H, T>, 0> {
  typedef H Result;
};

TypeAt<tlist, 3>::Result とすれば、tlist の3番目の要素を得ることが出来る。

loki の typelist.h 内には、これらの他にもタイプリストを操作する様々なテンプレートが定義されてゐる。