【C++泛型编程】Typelists型别工具

Typelists是一个用来操作一大群型别的C++工具,就像lists对数值提供各种基本操作一样。
1.定义Typelists
           Typelist是以一种特殊的型别结束:NullType

class NullType {};
 struct EmptyType {};        // could be instantiated

 template <class T, class U>
  struct Typelist
   
{
   typedef T Head;
     typedef U Tail;
 };


下面我们可以定义以NullType结束的型别,每个typelist都必须以NullType结尾。NullType可以视为一个结束记号,类似'\0'的功能。
typedef Typelist< char, Typelist<signed char,
             Typelist<unsigned char, NullType> > > Charlist;
 注:Typelists内部没有任何数值:他们的实体是空的,不含任何的状态,也未定义任何的函数。执行期间typelists也不带任何数值。它们存在的理由只是为了携带型别信息。因此,对typelist的任何
处理都一定发生在编译期而不是执行期。

2.将Typelist的生成线性化
 用宏来将递归形式转化成比较简单的枚举形式,取代比较冗长的的重复动作。Loki把Typelists的长度扩充到了50.

#define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
#define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) >
#define TYPELIST_4(T1, T2, T3, T4) \
 ::Loki::Typelist<T1, LOKI_TYPELIST_3(T2, T3, T4) >


现在可以用简单的方式定义Charlist了
typedef TYPELIST_3(char, signed char, unsigned char)  Charlist;

3.计算长度
       假设TList typelist,它有一个编译期常数代表其长度。因为typelists是一种静态构件,所以这个与typelists相关的计算在编译期完成。计算typelist长度的代码如下:

//
//  长度
//
template <class TList> struct Length;

template <>
struct Length<NullType> //Length的全特化,只匹配NullType
{
    enum { value = 0 };
};

template <class T, class U>
struct Length <Typelist<T,U> > //Length的偏特化,可以匹配任何Typelist<T,U>型别,包括复合型
{
    enum { value = 1 + Length<U>::value };
};




4.索引访问
       一个带有索引操作的template的声明式如下:
template<class TList,unsigned int index>struct TypeAt;

TypeAt:
输入:typelist TList,索引值i
输出:内部某型别Result
如果TList不为null且i=0,那么Result就是TList的头部
否则
如果TList不为null且i不为0,那么Result就是将TypeAt施行于TList尾端及i-1的结果
否则越界访问,造成编译错误。
TypeAt的算法如下:

template <class Head, class Tail>
struct TypeAt< TypeList<Head, Tail>, 0>
{
    typedef Head Result;
};

template <class Head, class Tail, unsigned int i>
struct TypeAt< TypeList<Head, Tail, i>
{
    typedef typename TypeAt<Tail,i-1>::Result Result;
};


5.查找Typelists
流程如下:

if TList is NullType then -1

if the Head is T then 0

if IndexOf(Tail,T)==-1 then -1

else IndexOf(Tail,T)+1

算法如下:

template <class TList, class T> struct IndexOf;

template <class T>
struct IndexOf< NullType, T>
{
    enum { value = -1 };
};

template <class T, class Tail>
struct IndexOf< Typelist<Head, Tail>, T>
{
private:
    enum { temp = IndexOf<Tail, T>::value };
public:
    enum { value = (temp == -1) ? -1 : 1+temp };
};


6.附加元素到Typelist


 

//
//  Append
//
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> >
{
    tyepdef 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;
};


使用方法如下:
typedef Append<SignedIntegrals,
            TYPELIST_3(float,double,long double)>::Result    SignedTypes;

7.移除Typelist中的某个元素

//
//  Erase
//
template <class TList, class T> struct Erase;

template <class T>
struct Erase< NullType, T>
{
    typedef NullType Result;
};

template <class T, clas Tail>
struct Erase< Typelist<T, Tail>, T>
{
    typedef Tail Result;
};

template <class Head, class Tail, class T>
struct Erase< TypeList<Head, Tail>, T>
{
    typedef TypeList<Head, typename Erase<Tail,T>::Result> Result;
};


使用方法:
typedef Erase<SignedTypes,float>::Result SomeSignedTypes;

移除所有的元素:

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;
   
     };


8.移除重复的元素
 

template <class TList> struct NoDuplicates;
template <> struct NoDuplicates<NullType>
   
   {
         
   typedef NullType Result;
     
   };


template <class Head, class 
struct NoDuplicates< Typelist<Head, Tail> >
   
     {
      
  private:
          
      typedef typename NoDuplicates<Tail>::Result L1;
       
      typedef typename Erase<L1, Head>::Result L2;
       
 public:
          
      typedef Typelist<Head, L2> Result;
    
    };


9.取代Typelist中的某个元素(以型别U取代型别T)
 

template <class TList, class T, class U> struct Replace;

   template <class T, class U>
      
  struct Replace<NullType, T, U>
     
{
typedef NullType Result;
      
  };

     
   template <class T, class Tail, class U>
    
    struct Replace<Typelist<T, Tail>, T, U>
      
  {
         
   typedef Typelist<U, Tail> Result;
   
     };

       
 template <class Head, class Tail, class T, class U>
      
  struct Replace<Typelist<Head, Tail>, T, U>
     
   {
           
 typedef Typelist<Head,
typename Replace<Tail, T, U>::Result>
    Result;
     
   };


10. 为Typelists局部更换次序
        让派生型别出现在基础型别之前。MostDerived算法接受一个typelist和一个Base型别,传回typelist中base的最深层派生型别。如果找不到任何派生型别,就返回Base自己。
如下:
 

template <class TList, class T> struct MostDerived;

 template <class T>
        
struct MostDerived<NullType, T>
  
      {
        
    typedef T Result;
   
     };
        
      、
  template <class Head, class Tail, class T>
     
   struct MostDerived<Typelist<Head, Tail>, T>
    
    {
       
 private:
     
       typedef typename MostDerived<Tail, T>::Result Candidate;
        
public:
           
 typedef typename Select<
  SuperSubclass<Candidate,Head>::value,
 
Head, Candidate>::Result Result;
   
     };


DerivedToFront算法是以MostDerivedwei为基础,如下:
 

template <class TList> struct DerivedToFront;
 
  template <>
        struct DerivedToFront<NullType>
    
   {
          
  typedef NullType Result;
  
      };
        
       
 template <class Head, class Tail>
 
       struct DerivedToFront< Typelist<Head, Tail> >
  
      {
        
private:
 
    typedef typename MostDerived<Tail, Head>::Result
   TheMostDerived;
         
   typedef typename Replace<Tail,
   TheMostDerived, Head>::Result Temp;
     
    typedef typename DerivedToFront<Temp>::Result L;
    
public:
            
    typedef Typelist<TheMostDerived, L> Result;
     
   };


DerivedToFront转换可以高效的将“型别处理工序”自动化。

你可能感兴趣的:(编程,C++,算法,struct,Class,float)