模板元编程(2):计算最值

模板元编程(2):计算最值
   本文就Loki编译期技术中的类型列表Typelist作了一些扩展,增加了以下几个方法:
      • 获取最大和最小长度,即求取Typelist中长度最大和最小的值  
      • 获取最大和最小类型,即求取Typelist中长度最大和最小的类型

实现
   位于Loki::TL命名空间,利用递归计算最值结果,使用宏生成主类模板和特化类模板,其中后缀为DEFN(N为正整数)形式的宏中N表示特化类模板所带的模板参数数量,使用DEF1宏定义对应的特化类模板的原因在于:当Typelist中存在非NullType类型时,保证结果的正确性。当N为2时参数取值:name为Max则b为true;name为Min则b为false。
    主类模板
   用于定义MaxSize、MinSize和MaxType、MinType主类模板,使用宏LOKI_TYPELIST_METHOD_DEF生成。 
1      #define  LOKI_TYPELIST_METHOD_DEF(name)\
2     template  < class  TList > \
3      struct  name;\
4     
5     LOKI_TYPELIST_METHOD_DEF(MaxSize)
6     LOKI_TYPELIST_METHOD_DEF(MinSize)
7     LOKI_TYPELIST_METHOD_DEF(MaxType)
8     LOKI_TYPELIST_METHOD_DEF(MinType)

    最大(小)长度
   对应类主模板分别为MaxSize和MinSize,每种有3个特化模板,使用宏LOKI_TYPELIST_SIZE_SPEC_DEFN生成(N为0、1、2)。
 1      #define  LOKI_TYPELIST_SIZE_SPEC_DEF0(name)\
 2     template <> \
 3      struct  name##Size < NullType > \
 4      {\
 5        enum { value = 0 };\
 6    }
;\
 7     
 8      #define  LOKI_TYPELIST_SIZE_SPEC_DEF1(name)\
 9     template < class  T > \
10      struct  name##Size < Typelist < T,NullType >   > \
11      {\
12        enum { value = sizeof(T) };\
13    }
;\
14     
15      #define  LOKI_TYPELIST_SIZE_SPEC_DEF2(name,b)\
16     template < class  T, class  U > \
17      struct  name##Size < Typelist < T,U >   > \
18      {\
19        enum { tmp = name##Size<U>::value };\
20        enum { value = (b ? sizeof(T) > tmp : sizeof(T) < tmp) ? sizeof(T) : tmp };\
21    }
;\
22     
23     LOKI_TYPELIST_SIZE_SPEC_DEF0(Max)
24     LOKI_TYPELIST_SIZE_SPEC_DEF0(Min)
25     LOKI_TYPELIST_SIZE_SPEC_DEF1(Max)
26     LOKI_TYPELIST_SIZE_SPEC_DEF1(Min)
27     LOKI_TYPELIST_SIZE_SPEC_DEF2(Max, true )
28     LOKI_TYPELIST_SIZE_SPEC_DEF2(Min, false )
29     
30      #undef  LOKI_TYPELIST_SIZE_SPEC_DEF0
31      #undef  LOKI_TYPELIST_SIZE_SPEC_DEF1
32      #undef  LOKI_TYPELIST_SIZE_SPEC_DEF2

    最大(小)类型
   对应类主模板分别为MaxType和MinType,每种有3个特化模板,使用宏LOKI_TYPELIST_TYPE_SPEC_DEFN生成(N为0、1、2)。   
 1      #define  LOKI_TYPELIST_TYPE_SPEC_DEF0(name)\
 2     template <> \
 3      struct  name##Type < NullType > \
 4      {\
 5        typedef NullType type;\
 6    }
;\
 7     
 8      #define  LOKI_TYPELIST_TYPE_SPEC_DEF1(name)\
 9     template < class  T > \
10      struct  name##Type < Typelist < T,NullType >   > \
11      {\
12        typedef T type;\
13    }
;\
14     
15      #define  LOKI_TYPELIST_TYPE_SPEC_DEF2(name,b)\
16     template < class  T, class  U > \
17      struct  name##Type < Typelist < T,U >   > \
18      {\
19        typedef typename name##Type<U>::type R;\
20        typedef typename Select< b ? (sizeof(T)>sizeof(R)) : (sizeof(T)<sizeof(R)),T,R>::Result type;\
21    }
;\
22     
23     LOKI_TYPELIST_TYPE_SPEC_DEF0(Max)
24     LOKI_TYPELIST_TYPE_SPEC_DEF0(Min)
25     LOKI_TYPELIST_TYPE_SPEC_DEF1(Max)
26     LOKI_TYPELIST_TYPE_SPEC_DEF1(Min)
27     LOKI_TYPELIST_TYPE_SPEC_DEF2(Max, true )
28     LOKI_TYPELIST_TYPE_SPEC_DEF2(Min, false )
29     
30      #undef  LOKI_TYPELIST_TYPE_SPEC_DEF0
31      #undef  LOKI_TYPELIST_TYPE_SPEC_DEF1
32      #undef  LOKI_TYPELIST_TYPE_SPEC_DEF2
   这里用到了Loki中的Select组件来选择类型。

示例
   使用LOKI中的LOKI_STATIC_CHECK宏来做编译期诊断结果正确性。
 1 #define  LOKI_TL4 LOKI_TYPELIST_4(double,int,short,char) 
 2
 3 int  main( int  argc, char   * argv[])
 4 {
 5    static const int max_val = Loki::TL::MaxSize<LOKI_TL4 >::value;
 6    LOKI_STATIC_CHECK(max_val==sizeof(double),max_val_should_be_sizeof_double)
 7
 8    static const int min_val = Loki::TL::MinSize<LOKI_TL4 >::value;
 9    LOKI_STATIC_CHECK(min_val==sizeof(char),min_val_should_be_sizeof_char)
10
11    typedef Loki::TL::MaxType<LOKI_TL4 >::type max_type;
12    LOKI_STATIC_CHECK((Loki::IsSameType<max_type,double>::value),max_type_should_be_double)
13
14    typedef Loki::TL::MinType<LOKI_TL4 >::type min_type;
15    LOKI_STATIC_CHECK((Loki::IsSameType<min_type,char>::value),min_type_should_be_char)
16
17    return 0;
18}

你可能感兴趣的:(模板元编程(2):计算最值)