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

时间:2023-01-30 19:24:48
 

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

分类: C/C++、STL、泛型编程 321人阅读 评论(0) 收藏 举报 c++编程classstruct算法float http://blog.csdn.net/xiaoding133/article/details/7935309

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

[cpp] view plaincopy
  1. class NullType {};  
  2.  struct EmptyType {};        // could be instantiated  
  3.   
  4.  template <class T, class U>  
  5.   struct Typelist  
  6.      
  7. {  
  8.    typedef T Head;  
  9.      typedef U Tail;  
  10.  };  


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

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

[cpp] view plaincopy
  1. #define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>  
  2. #define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) >  
  3. #define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) >  
  4. #define TYPELIST_4(T1, T2, T3, T4) \  
  5.  ::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长度的代码如下:

[cpp] view plaincopy
  1. //  
  2. //  长度  
  3. //  
  4. template <class TList> struct Length;  
  5.   
  6. template <>  
  7. struct Length<NullType> //Length的全特化,只匹配NullType  
  8. {  
  9.     enum { value = 0 };  
  10. };  
  11.   
  12. template <class T, class U>  
  13. struct Length <Typelist<T,U> > //Length的偏特化,可以匹配任何Typelist<T,U>型别,包括复合型  
  14. {  
  15.     enum { value = 1 + Length<U>::value };  
  16. };  


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的算法如下:

[cpp] view plaincopy
  1. template <class Head, class Tail>  
  2. struct TypeAt< TypeList<Head, Tail>, 0>  
  3. {  
  4.     typedef Head Result;  
  5. };  
  6.   
  7. template <class Head, class Tail, unsigned int i>  
  8. struct TypeAt< TypeList<Head, Tail, i>  
  9. {  
  10.     typedef typename TypeAt<Tail,i-1>::Result Result;  
  11. };  


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

算法如下:

[cpp] view plaincopy
  1. template <class TList, class T> struct IndexOf;  
  2.   
  3. template <class T>  
  4. struct IndexOf< NullType, T>  
  5. {  
  6.     enum { value = -1 };  
  7. };  
  8.   
  9. template <class T, class Tail>  
  10. struct IndexOf< Typelist<Head, Tail>, T>  
  11. {  
  12. private:  
  13.     enum { temp = IndexOf<Tail, T>::value };  
  14. public:  
  15.     enum { value = (temp == -1) ? -1 : 1+temp };  
  16. };  


6.附加元素到Typelist


 

[cpp] view plaincopy
  1. //  
  2. //  Append  
  3. //  
  4. template <class TList, class T> struct Append;  
  5.   
  6. template <>  
  7. struct Append< NullType, NullType>  
  8. {  
  9.     typedef NullType Result;  
  10. };  
  11. template <class T>  
  12. struct Append< NullType, T>  
  13. {  
  14.     typedef TYPELIST_1(T) Result;  
  15. };  
  16. template <class Head, class Tail>  
  17. struct Append< NullType, Typelist<Head,Tail> >  
  18. {  
  19.     tyepdef Typelist<Head,Tail> Result;  
  20. };  
  21. template <class Head, class Tail, class T>  
  22. struct Append< Typelist<Head,Tail>, T>  
  23. {  
  24.     typedef Typelist<Head, typename Append<Tail,T>::Result> Result;  
  25. };  


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

7.移除Typelist中的某个元素

[cpp] view plaincopy
  1. //  
  2. //  Erase  
  3. //  
  4. template <class TList, class T> struct Erase;  
  5.   
  6. template <class T>  
  7. struct Erase< NullType, T>  
  8. {  
  9.     typedef NullType Result;  
  10. };  
  11.   
  12. template <class T, clas Tail>  
  13. struct Erase< Typelist<T, Tail>, T>  
  14. {  
  15.     typedef Tail Result;  
  16. };  
  17.   
  18. template <class Head, class Tail, class T>  
  19. struct Erase< TypeList<Head, Tail>, T>  
  20. {  
  21.     typedef TypeList<Head, typename Erase<Tail,T>::Result> Result;  
  22. };  


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

移除所有的元素:

[cpp] view plaincopy
  1. template <class TList, class T> struct EraseAll;  
  2.       
  3. template <class T>  
  4.       
  5.   struct EraseAll<NullType, T>  
  6.       
  7.     {  
  8.             
  9.   typedef NullType Result;  
  10.       
  11.     };  
  12.        
  13.    template <class T, class Tail>  
  14.         
  15.   struct EraseAll<Typelist<T, Tail>, T>  
  16.         
  17.   {  
  18.             // Go all the way down the list removing the type  
  19.               
  20. typedef typename EraseAll<Tail, T>::Result Result;  
  21.       
  22.     };  
  23.        
  24.    template <class Head, class Tail, class T>  
  25.           
  26. struct EraseAll<Typelist<Head, Tail>, T>  
  27.          
  28.  {  
  29.           
  30.     // Go all the way down the list removing the type  
  31.            
  32.    typedef Typelist<Head,   
  33.                       
  34. typename EraseAll<Tail, T>::Result>  
  35.      Result;  
  36.      
  37.      };  


8.移除重复的元素
 

[cpp] view plaincopy
  1. template <class TList> struct NoDuplicates;  
  2. template <> struct NoDuplicates<NullType>  
  3.      
  4.    {  
  5.            
  6.    typedef NullType Result;  
  7.        
  8.    };  
  9.   
  10.   
  11. template <class Head, class   
  12. struct NoDuplicates< Typelist<Head, Tail> >  
  13.      
  14.      {  
  15.         
  16.   private:  
  17.             
  18.       typedef typename NoDuplicates<Tail>::Result L1;  
  19.          
  20.       typedef typename Erase<L1, Head>::Result L2;  
  21.          
  22.  public:  
  23.             
  24.       typedef Typelist<Head, L2> Result;  
  25.       
  26.     };  


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

[cpp] view plaincopy
  1. template <class TList, class T, class U> struct Replace;  
  2.   
  3.    template <class T, class U>  
  4.         
  5.   struct Replace<NullType, T, U>  
  6.        
  7. {  
  8. typedef NullType Result;  
  9.         
  10.   };  
  11.   
  12.        
  13.    template <class T, class Tail, class U>  
  14.       
  15.     struct Replace<Typelist<T, Tail>, T, U>  
  16.         
  17.   {  
  18.            
  19.    typedef Typelist<U, Tail> Result;  
  20.      
  21.      };  
  22.   
  23.          
  24.  template <class Head, class Tail, class T, class U>  
  25.         
  26.   struct Replace<Typelist<Head, Tail>, T, U>  
  27.        
  28.    {  
  29.              
  30.  typedef Typelist<Head,  
  31. typename Replace<Tail, T, U>::Result>  
  32.     Result;  
  33.        
  34.    };  


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

[cpp] view plaincopy
  1. template <class TList, class T> struct MostDerived;  
  2.   
  3.  template <class T>  
  4.           
  5. struct MostDerived<NullType, T>  
  6.     
  7.       {  
  8.           
  9.     typedef T Result;  
  10.      
  11.      };  
  12.           
  13.       、  
  14.   template <class Head, class Tail, class T>  
  15.        
  16.    struct MostDerived<Typelist<Head, Tail>, T>  
  17.       
  18.     {  
  19.          
  20.  private:  
  21.        
  22.        typedef typename MostDerived<Tail, T>::Result Candidate;  
  23.           
  24. public:  
  25.              
  26.  typedef typename Select<  
  27.   SuperSubclass<Candidate,Head>::value,  
  28.    
  29. Head, Candidate>::Result Result;  
  30.      
  31.      };  


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

[cpp] view plaincopy
  1. template <class TList> struct DerivedToFront;  
  2.    
  3.   template <>  
  4.         struct DerivedToFront<NullType>  
  5.       
  6.    {  
  7.             
  8.   typedef NullType Result;  
  9.     
  10.       };  
  11.           
  12.          
  13.  template <class Head, class Tail>  
  14.    
  15.        struct DerivedToFront< Typelist<Head, Tail> >  
  16.     
  17.       {  
  18.           
  19. private:  
  20.    
  21.     typedef typename MostDerived<Tail, Head>::Result  
  22.    TheMostDerived;  
  23.            
  24.    typedef typename Replace<Tail,  
  25.    TheMostDerived, Head>::Result Temp;  
  26.        
  27.     typedef typename DerivedToFront<Temp>::Result L;  
  28.       
  29. public:  
  30.               
  31.     typedef Typelist<TheMostDerived, L> Result;  
  32.        
  33.    };  


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