3.8 Appending to Typelists
We need a means to append a type or a typelist to a typelist. Because modifying a typelist is not possible, as discussed previously, we will "return by value" by creating a brand new typelist that contains the result.
Append Inputs: Typelist TList, type or typelist T Output: Inner type definition Result
If TList is NullType and T is NullType, then Result is NullType. Else If TList is NullType and T is a single (nontypelist) type, then Result is a typelist hav- ing T as its only element. Else If TList is NullType and T is a typelist, Result is T itself. Else if TList is non-null, then Result is a typelist having TList::Head as its head and the result of appending T to TList::Tail as its tail.
This algorithm maps naturally to the following code:
template <class TList, class T> struct Append;
template <> struct Append<NullType, NullType>
{
typedef NullType Result;
};
template <class T> struct Append<NullType, T>
{
typedef TYPELIST_1(T) Result;
};
template <class Head, class Tail>
struct Append<NullType, Typelist<Head, Tail> >
{
typedef Typelist<Head, Tail> Result;
};
template <class Head, class Tail, class T>
struct Append<Typelist<Head, Tail>, T>
{
typedef Typelist<Head,
typename Append<Tail, T>::Result>
Result;
};
Note, again, how the last partially specialized version of Append instantiates the Append template recursively, passing it the tail of the list and the type to append.
Now we have a unified Append operation for single types and typelists. For instance, the statement
typedef Append<SignedIntegrals,
TYPELIST_3(float, double, long double)>::Result
SignedTypes;
defines a list containing all signed numeric types in C++.
|