第三章 Typelists
2018-04-15 本文已影响0人
szn好色仙人
#include <typeinfo>
#include <cstdio>
//第二章已讨论过的一些函数,现在拿来使用
template<bool bRe, typename T, typename U>
struct SSelect { typedef T Type; };
template<typename T, typename U>
struct SSelect<false, T, U> { typedef U Type; };
template<typename T, typename U>
class CConversion
{
typedef char Small;
class CBig { char aBuff[2]; };
static Small Fun(U);
static CBig Fun(...);
static T MakeT();
public:
enum { eExists = sizeof(Fun(MakeT())) == sizeof(Small) };
enum { eExistsToWay = eExists && CConversion<U, T>::eExists };
enum { eSameType = false };
};
template<typename T>
class CConversion<T, T>
{
public:
enum { eExists = true, eExistsToWay = true, eSameType = true };
};
template<int nValue>
struct IntToType
{
enum { eValue = nValue };
};
//核心代码
struct SNullType; //不进行实现,充当类型终止符
template<typename T, typename U>
struct STypeList
{
typedef T Type_Head;
typedef U Type_Tail;
};
//别名定义
#define STYPELIST_1(T1) STypeList<T1, SNullType>
#define STYPELIST_2(T1, T2) STypeList<T1, STYPELIST_1(T2)>
#define STYPELIST_3(T1, T2, T3) STypeList<T1, STYPELIST_2(T2, T3)>
#define STYPELIST_4(T1, T2, T3, T4) STypeList<T1, STYPELIST_3(T2, T3, T4)>
//... 可以无限延伸
//#define STYPELIST_100(...)
//长度运算
template<typename T> struct SLength;
template<> struct SLength<SNullType> { enum { nLength = 0}; };
template<typename T, typename U> struct SLength< STypeList<T, U> >
{
enum { nLength = 1 + SLength<U>::nLength }; //将自动递归展开
};
//类似索引访问
template<typename T, unsigned int nId> struct STypeAt;
//偏特化前要进行声明,且不进行定义则当访问越界时编译会失败
template<typename T, typename U>
struct STypeAt< STypeList<T, U>, 0>
{
typedef T Result;
};
template<typename T, typename U, unsigned int nId>
struct STypeAt<STypeList<T, U>, nId>
{
typedef typename STypeAt<U, nId - 1>::Result Result;//将自动展开递归
};
//STypeAt模板类的展开是在编译器完成的,不会影响运行效率
//类型查找
template<typename TList, typename U> struct SFind;
template<typename U>
struct SFind<SNullType, U>
{
enum { nId = -1 }; //被查找的类型不在类型列表中
};
template<typename T_Tail, typename U>
struct SFind<STypeList<U, T_Tail>, U>
{
enum { nId = 0 };
};
template<typename T_Head, typename T_Tail, typename U>
struct SFind<STypeList<T_Head, T_Tail>, U>
{
private:
enum { nTem = SFind<T_Tail, U>::nId }; //将自动展开递归
public:
enum { nId = nTem == -1 ? -1 : 1 + nTem };
};
//附加元素
template<typename TList, typename U> struct SAppend;
template<> struct SAppend<SNullType, SNullType>
{
typedef SNullType Type_NewType;
};
template<typename U> struct SAppend<SNullType, U>
{
typedef STYPELIST_1(U) Type_NewType;
};
template<typename T_Head, typename T_Tail>
struct SAppend<SNullType, STypeList<T_Head, T_Tail>>
{
typedef STypeList<T_Head, T_Tail> Type_NewType;
};
template<typename T_Head, typename T_Tail, typename U>
struct SAppend<STypeList<T_Head, T_Tail>, U>
{
typedef STypeList<T_Head, typename SAppend<T_Tail, U>::Type_NewType>
Type_NewType; //愉快的自动展开递归
};
//移除元素
template<typename TList, typename U> struct SErase;
template<typename T>
struct SErase<SNullType, T>
{
typedef SNullType Type_NewType;
};
template<typename T, typename T_Tail>
struct SErase<STypeList<T, T_Tail>, T>
{
typedef T_Tail Type_NewType;
};
template<typename T_Head, typename T_Tail, typename T>
struct SErase<STypeList<T_Head, T_Tail>, T>
{
typedef STypeList<T_Head, typename SErase<T_Tail, T>::Type_NewType>
Type_NewType;
};
//移除某个类型的全部元素
template<typename TList, typename U> struct SEraseAll;
template<typename T>
struct SEraseAll<SNullType, T>
{
typedef SNullType Type_NewType;
};
template<typename T, typename T_Tail>
struct SEraseAll<STypeList<T, T_Tail>, T>
{
//和SErase唯一的区别:发现符合条件项后并不停止,而是继续查找
typedef typename SEraseAll<T_Tail, T>::Type_NewType Type_NewType;
};
template<typename T_Head, typename T_Tail, typename T>
struct SEraseAll<STypeList<T_Head, T_Tail>, T>
{
typedef STypeList<T_Head, typename SEraseAll<T_Tail, T>::Type_NewType>
Type_NewType;
};
//去重
template<typename TList> struct SNoDumplicate;
template<> struct SNoDumplicate<SNullType>
{
typedef SNullType Type_NewType;
};
template<typename T_Head, typename T_Tail>
struct SNoDumplicate<STypeList<T_Head, T_Tail>>
{
private:
typedef typename SNoDumplicate<T_Tail>::Type_NewType T0;
typedef typename SErase<T0, T_Head>::Type_NewType T1;
public:
typedef STypeList<T_Head, T1> Type_NewType;
};
//替换首个匹配类型
template<typename TList, typename T, typename U> struct SReplace;
template<typename T, typename U>
struct SReplace<SNullType, T, U>
{
typedef SNullType Type_NewType;
};
template<typename T, typename T_Tail, typename U>
struct SReplace<STypeList<T, T_Tail>, T, U>
{
typedef STypeList<U, T_Tail> Type_NewType;
};
template<typename T_Head, typename T_Tail, typename T, typename U>
struct SReplace<STypeList<T_Head, T_Tail>, T, U>
{
typedef STypeList<T_Head, typename SReplace<T_Tail, T, U>
::Type_NewType> Type_NewType;
};
//替换全部匹配类型 书上没有,自己编的
template<typename TList, typename T, typename U> struct SReplaceAll;
template<typename T, typename U>
struct SReplaceAll<SNullType, T, U>
{
typedef SNullType Type_NewType;
};
template<typename T, typename T_Tail, typename U>
struct SReplaceAll<STypeList<T, T_Tail>, T, U>
{
typedef typename SReplaceAll<STypeList<U, T_Tail>, T, U>::Type_NewType
Type_NewType;
};
template<typename T_Head, typename T_Tail, typename T, typename U>
struct SReplaceAll<STypeList<T_Head, T_Tail>, T, U>
{
typedef STypeList<T_Head, typename SReplaceAll<T_Tail, T, U>
::Type_NewType> Type_NewType;
};
//类型局部更改次序
template<typename TList, typename T> struct SMostDerived;
template<typename T> struct SMostDerived<SNullType, T>
{
typedef T Type_NewType;
};
template<typename T_Head, typename T_Tail, typename T>
struct SMostDerived<STypeList<T_Head, T_Tail>, T>
{
private:
typedef typename SMostDerived<T_Tail, T>::Type_NewType TCandidate;
public:
typedef typename SSelect<CConversion<TCandidate, T_Head>::eExists,
T_Head, TCandidate>::Type Type_NewType;
/*
typedef typename SSelect<CConversion<TCandidate, T_Head>::eExists,
T_Head, TCandidate>::Type Type_NewType 的意思:
结论一:
TCandidate 是 T_Head 的派生类吗,
若是,则T_Head是父类,则Type_NewType = T_Head
若否,则Type_NewType = TCandidate本身
结论二:
TCandidate本身是一个递归,由结论一可知:
TCandidate是T_Tail中T类型的最底层基类或者是T类型本身
由上推知Type_NewType就是类型T的最底层基类类型
*/
};
template<typename T> struct SDerivedToFront;
template<> struct SDerivedToFront<SNullType>
{
typedef SNullType Type_NewType;
};
template<typename T_Head, typename T_Tail>
struct SDerivedToFront<STypeList<T_Head, T_Tail>>
{
private:
typedef typename SMostDerived<T_Tail, T_Head>::Type_NewType T_Tem0;
typedef typename SReplace<T_Tail, T_Tem0, T_Head>::Type_NewType
T_Tem1;
public:
typedef typename STypeList<T_Tem0, T_Tem1> Type_NewType;
};
class CF {};
class CC : public CF {};
class CCC : public CC {};
//产生散乱的继承体系
template<typename T, template<typename> class CUnit> class CTest;
template<typename T, typename U, template<typename> class CUnit>
class CTest<STypeList<T, U>, CUnit> :
public CTest<T, CUnit>, public CTest<U, CUnit>
{
public:
CTest()
{
printf("%s\n", typeid(STypeList<T, U>).name());
}
};
template<typename T, template<typename> class CUnit> class CTest :
public CUnit<T>
{
public:
CTest()
{
printf("%s\n", typeid(T).name());
}
};
template<template<typename> class CUnit> class CTest<SNullType, CUnit>
{
public:
CTest(){printf("SNullType\n");}
};
template<typename T, typename TList, template<typename> class CUnit>
CUnit<T>& Field(CTest<TList, CUnit>& Test)
{
//CUnit<T>是CTest<TList, CUnit> 的父类,这里是父类的引用接收派生类的对象
//当TList存在2个相同类型的时候,此转换函数就不好用了
return Test;
}
template<typename TList, template<typename> class CUnit>
CUnit<typename TList::Type_Head>& FieldHelper(CTest<TList, CUnit>& Test,
IntToType<0>)
{
CTest<TList::Type_Head, CUnit>& Tem = Test;
return Tem;
}
template<int nId, typename TList, template<typename> class CUnit>
CUnit<typename STypeAt<TList, nId>::Result>& FieldHelper(CTest<TList,
CUnit>& Test, IntToType<nId>)
{
CTest<TList::Type_Tail, CUnit>& Tem = Test;
return FieldHelper(Tem, IntToType<nId - 1>());
}
template<int nId, typename TList, template<typename> class CUnit>
CUnit<typename STypeAt<TList, nId>::Result>& Field
(CTest<TList, CUnit>& Test)
{
return FieldHelper(Test, IntToType<nId>());
}
template<int nId, typename TList, template<typename> class CUnit>//自己编的
typename STypeAt<TList, nId>::Result & MyGet(CTest<TList, CUnit>& Test)
{
return FieldHelper(Test, IntToType<nId>()).tValue;//结合 SValue 使用
}
template<typename T> struct SValue
{
T tValue;
protected:
~SValue(){}
};
//产生线性继承体系
template<typename TList, template<typename T, typename TBase> class CUnit,
typename TRoot = SNullType>
class CLineCreate;
template<typename T1, typename T2,
template<typename, typename> class CUnit, typename TRoot>
class CLineCreate<STypeList<T1, T2>, CUnit, TRoot> :
public CUnit<T1, CLineCreate<T2, CUnit, TRoot>>
{
};
template<typename T, template<typename, typename> class CUnit,
typename TRoot>
class CLineCreate<STYPELIST_1(T), CUnit, TRoot> : public CUnit<T, TRoot>
{
};
template<typename T>
class CData
{
public:
virtual void Fun() {}
virtual ~CData() {}
};
template<typename T, typename TBase>
class CData1 : public TBase
{
public:
virtual void Fun() {}
};
class CBase
{
public:
virtual ~CBase(){}
};
int main()
{
const char* aStr0[] =
{
typeid(STYPELIST_3(int, double, float)::Type_Head).name(),
//"int"
typeid(STYPELIST_2(int, double)::Type_Tail::Type_Head).name(),
//"double"
typeid(STypeAt<STYPELIST_3(int, double, float), 2>::Result).name()
//"float"
};
//typeid(STypeAt<STYPELIST_3(int, double, float), 3>::Result).name();
//error C2027: 使用了未定义类型“STypeAt<T,nId>”
int nLen = SLength<STYPELIST_4(int, double, float, char)>::nLength;
//nLen = 4
int aId[] =
{
SFind<STYPELIST_3(int, double, float), int>::nId, //0
SFind<STYPELIST_3(int, double, float), double>::nId,//1
SFind<STYPELIST_3(int, double, float), float>::nId, //2
SFind<STYPELIST_3(int, double, float), char>::nId, //-1
};
const char* aStr1[] =
{
typeid(SAppend<SNullType, SNullType>::Type_NewType).name(),
//"struct SNullType"
typeid(SAppend<SNullType, char>::Type_NewType).name(),
//"struct STypeList<char,struct SNullType>"
typeid(SAppend<STYPELIST_1(char), int>::Type_NewType).name()
//"struct STypeList<char,struct STypeList<int,struct SNullType> >"
};
//元素全为true
bool aRe[] =
{
typeid(SAppend<STYPELIST_2(int, double), char>::Type_NewType)
== typeid(STYPELIST_3(int, double, char)),
typeid(SErase<STYPELIST_4(int, double, char, double), double>
::Type_NewType) == typeid(STYPELIST_3(int, char, double)),
typeid(SEraseAll<STYPELIST_4(int, double, char, double), double>::
Type_NewType) == typeid(STYPELIST_2(int, char)),
typeid(SNoDumplicate<STYPELIST_4(int, double, char, double)>::
Type_NewType) == typeid(STYPELIST_3(int, double, char)),
typeid(SReplace<STYPELIST_4(int, double, char, double), double,
long>::Type_NewType) == typeid(STYPELIST_4(int, long, char,
double)),
typeid(SReplaceAll<STYPELIST_4(int, double, char, double), double,
long>::Type_NewType) == typeid(STYPELIST_4(int, long, char,
long))
};
const char* pStr = typeid
(SMostDerived<STYPELIST_2(CC, CF), CCC>::Type_NewType).name();
//"class CF"
bool nRe = typeid(SDerivedToFront<STYPELIST_4(CC, CF, CCC, CF)>
::Type_NewType) == typeid(STYPELIST_4(CF, CC, CCC, CF));
//nRe = true
CTest<STYPELIST_3(int, bool, double), SValue> Test;
/*
输出:
int
bool
double
SNullType
struct STypeList<double, struct SNullType>
struct STypeList<bool, struct STypeList<double, struct SNullType>>
struct STypeList<int, struct STypeList<bool,
struct STypeList<double, struct SNullType>>>
*/
/*
Test对象的继承的基类:
SValue<int>
SValue<bool>
SValue<double>
CTest<int,SValue>
CTest<bool,SValue>
CTest<double,SValue>
CTest<SNullType,SValue>
CTest<STypeList<double,SNullType>,SValue>
CTest<STypeList<bool,STypeList<double,SNullType>>,SValue>
*/
(static_cast<SValue<int>&>(Test)).tValue = 0;
(static_cast<SValue<double>&>(Test)).tValue = 0.1;
Field<bool>(Test).tValue = true;
CTest<STYPELIST_3(int, int, double), SValue> Test1;
//warning C4584: “CTest<T,CUnit>”:
// 基类“CTest<T,CUnit>”已是“CTest<T,CUnit>”的基类
//Field<int>(Test1).tValue = 1;
//error C2594: “return”: 从“CTest<T,CUnit>”到“SValue<T> &”的转换不明确
Field<1>(Test1).tValue = 1; //第二个int成功被置为1
//自己实现tuple
CTest<STYPELIST_4(int, char, double, bool), SValue> Test2;
MyGet<0>(Test2) = 1;
MyGet<1>(Test2) = 2;
MyGet<2>(Test2) = 1.1;
MyGet<3>(Test2) = true;
//Test2 中对应值均正确
CTest<STYPELIST_3(int, char, double), CData> Data;
int nSize = sizeof Data; //nSize = 12 虚函数导致的开销 Win32环境
//Data对象的基类中的CData<int>,CData<char>,CData<double>具有虚函数
CLineCreate<STYPELIST_3(int, bool, double), CData1, CBase> Data1;
int nSize1 = sizeof Data1; //nSize1 = 4
/*
Data1对象的继承基类
CData1<double,CBase>
CLineCreate<STypeList<double,SNullType>,CData1,CBase>
CData1<bool,CLineCreate<STypeList<double,SNullType>,CData1,CBase> >
CLineCreate<STypeList<bool,STypeList<double,SNullType> >,CData1,CBase>
CData1<int,CLineCreate<STypeList<bool,STypeList<double,SNullType> >,
CData1,CBase> >
*/
return 0;
}