I l@ve RuBoard Previous Section Next Section

3.9 Erasing a Type from a Typelist

Now for the opposite operation— erasing a type from a typelist—we have two options: Erase only the first occurrence, or erase all occurrences of a given type.

Let's think of removing only the first occurrence.


   Erase
   Input: Typelist TList, type T
   Output: Inner type definition Result

   If TList is NullType, then Result is NullType.
   Else
     If T is the same as TList::Head, then Result is TList::Tail.
     Else Result is a typelist having TList::Head as its head and the result of applying
       Erase to TList::Tail and T as its tail.

Here's how this algorithm maps to C++.



template <class TList, class T> struct Erase;





template <class T>                         // Specialization 1


struct Erase<NullType, T>


{


   typedef NullType Result;


};





template <class T, class Tail>             // Specialization 2


struct Erase<Typelist<T, Tail>, T>


{


   typedef Tail Result;


};





template <class Head, class Tail, class T> // Specialization 3


struct Erase<Typelist<Head, Tail>, T>


{


   typedef Typelist<Head,


         typename Erase<Tail, T>::Result>


      Result;


};


As in the case of TypeAt, there is no default version of the template. This means you can instantiate Erase only with certain types. For instance, Erase<double, int> yields a compile-time error because there's no match for it. Erase needs its first parameter to be a typelist.

Using our SignedTypes definition, we can now say the following:



// SomeSignedTypes contains the equivalent of


// TYPELIST_6(signed char, short int, int, long int,


// double, long double)


typedef Erase<SignedTypes, float>::Result SomeSignedTypes;


Let's tap into the recursive erase algorithm. The EraseAll template erases all occurrences of a type in a typelist. The implementation is similar to Erase's, with one difference. When detecting a type to erase, the algorithm doesn't stop. EraseAll continues looking for and removing matches down the tail of the list by recursively applying itself:



template <class TList, class T> struct EraseAll;





template <class T>


struct EraseAll<NullType, T>


{


   typedef NullType Result;


};





template <class T, class Tail>


struct EraseAll<Typelist<T, Tail>, T>


{


   // Go all the way down the list removing the type


   typedef typename EraseAll<Tail, T>::Result Result;


};





template <class Head, class Tail, class T>


struct EraseAll<Typelist<Head, Tail>, T>


{


   // Go all the way down the list removing the type


   typedef Typelist<Head,


         typename EraseAll<Tail, T>::Result>


      Result;


};


    I l@ve RuBoard Previous Section Next Section