美文网首页
第三章 Typelists

第三章 Typelists

作者: szn好色仙人 | 来源:发表于2018-04-15 18:51 被阅读0次
#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;
}

相关文章

网友评论

      本文标题:第三章 Typelists

      本文链接:https://www.haomeiwen.com/subject/gvsdkftx.html