第三章 Typelists

#include 
#include 


//第二章已讨论过的一些函数,现在拿来使用
template
struct SSelect  { typedef T Type; };
template
struct SSelect { typedef U Type; };

template
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::eExists };
    enum { eSameType = false };
};
template
class CConversion
{
public:
    enum { eExists = true, eExistsToWay = true, eSameType = true };
};

template
struct IntToType
{
    enum { eValue = nValue };
};


//核心代码
struct SNullType;   //不进行实现,充当类型终止符
template
struct STypeList
{
    typedef T Type_Head;
    typedef U Type_Tail;
};


//别名定义
#define STYPELIST_1(T1) STypeList
#define STYPELIST_2(T1, T2) STypeList
#define STYPELIST_3(T1, T2, T3) STypeList
#define STYPELIST_4(T1, T2, T3, T4) STypeList
//...   可以无限延伸
//#define STYPELIST_100(...)


//长度运算
template struct SLength;
template<> struct SLength { enum { nLength = 0}; };
template struct SLength< STypeList >
{
    enum { nLength = 1 + SLength::nLength }; //将自动递归展开
};


//类似索引访问
template struct STypeAt;
//偏特化前要进行声明,且不进行定义则当访问越界时编译会失败

template
struct STypeAt< STypeList, 0>
{
    typedef T Result;
};
template
struct STypeAt, nId>
{
    typedef typename STypeAt::Result Result;//将自动展开递归
};
//STypeAt模板类的展开是在编译器完成的,不会影响运行效率


//类型查找
template struct SFind;
template
struct SFind
{
    enum { nId = -1 };  //被查找的类型不在类型列表中
};
template
struct SFind, U>
{
    enum { nId = 0 };
};
template
struct SFind, U>
{
private:
    enum { nTem = SFind::nId };  //将自动展开递归
public:
    enum { nId = nTem == -1 ? -1 : 1 + nTem };
};


//附加元素
template struct SAppend;
template<> struct SAppend
{
    typedef SNullType Type_NewType;
};
template struct SAppend
{
    typedef STYPELIST_1(U) Type_NewType;
};
template
struct SAppend>
{
    typedef STypeList Type_NewType;
};
template
struct SAppend, U>
{
    typedef STypeList::Type_NewType>
        Type_NewType;   //愉快的自动展开递归
};


//移除元素
template struct SErase;
template
struct SErase
{
    typedef SNullType Type_NewType;
};
template
struct SErase, T>
{
    typedef T_Tail Type_NewType;
};
template
struct SErase, T>
{
    typedef STypeList::Type_NewType> 
        Type_NewType;
};

//移除某个类型的全部元素
template struct SEraseAll;
template
struct SEraseAll
{
    typedef SNullType Type_NewType;
};
template
struct SEraseAll, T>
{
    //和SErase唯一的区别:发现符合条件项后并不停止,而是继续查找
    typedef typename SEraseAll::Type_NewType Type_NewType;
};
template
struct SEraseAll, T>
{
    typedef STypeList::Type_NewType>
        Type_NewType;
};


//去重
template struct SNoDumplicate;
template<> struct SNoDumplicate
{
    typedef SNullType Type_NewType;
};
template
struct SNoDumplicate>
{
private:
    typedef typename SNoDumplicate::Type_NewType T0;
    typedef typename SErase::Type_NewType T1;

public:
    typedef STypeList Type_NewType;
};


//替换首个匹配类型
template struct SReplace;
template
struct SReplace
{
    typedef SNullType Type_NewType;
};
template
struct SReplace, T, U>
{
    typedef STypeList Type_NewType;
};
template
struct SReplace, T, U>
{
    typedef STypeList
        ::Type_NewType> Type_NewType;
};

//替换全部匹配类型  书上没有,自己编的
template struct SReplaceAll;
template
struct SReplaceAll
{
    typedef SNullType Type_NewType;
};
template
struct SReplaceAll, T, U>
{
    typedef typename SReplaceAll, T, U>::Type_NewType
        Type_NewType;
};
template
struct SReplaceAll, T, U>
{
    typedef STypeList
        ::Type_NewType> Type_NewType;
};


//类型局部更改次序 
template struct SMostDerived;
template struct SMostDerived
{
    typedef T Type_NewType; 
};
template
struct SMostDerived, T>
{
private:
    typedef typename SMostDerived::Type_NewType TCandidate;

public:
    typedef typename SSelect::eExists, 
        T_Head, TCandidate>::Type Type_NewType;
    /*
    typedef typename SSelect::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 struct SDerivedToFront;
template<> struct SDerivedToFront
{
    typedef SNullType Type_NewType;
};
template
struct SDerivedToFront>
{
private:
    typedef typename SMostDerived::Type_NewType T_Tem0;
    typedef typename SReplace::Type_NewType 
        T_Tem1;

public:
    typedef typename STypeList Type_NewType;
};

class CF {};
class CC : public CF {};
class CCC : public CC {};


//产生散乱的继承体系
template class CUnit> class CTest;
template class CUnit>
class CTest, CUnit> :
    public CTest, public CTest
{
public:
    CTest()
    {
        printf("%s\n", typeid(STypeList).name());
    }
};
template class CUnit> class CTest : 
public CUnit 
{
public:
    CTest()
    {
        printf("%s\n", typeid(T).name());
    }
};
template class CUnit> class CTest 
{
public:
    CTest(){printf("SNullType\n");}
};

template class CUnit>
CUnit& Field(CTest& Test)  
{ 
    //CUnit是CTest 的父类,这里是父类的引用接收派生类的对象
    //当TList存在2个相同类型的时候,此转换函数就不好用了
    return Test; 
}
template class CUnit>
CUnit& FieldHelper(CTest& Test,
    IntToType<0>)
{
    CTest& Tem = Test;
    return Tem;
}
template class CUnit>
CUnit::Result>& FieldHelper(CTest& Test, IntToType)
{
    CTest& Tem = Test;
    return FieldHelper(Tem, IntToType());
}
template class CUnit>
CUnit::Result>& Field
    (CTest& Test) 
{
    return FieldHelper(Test, IntToType());
}

template class CUnit>//自己编的
typename STypeAt::Result & MyGet(CTest& Test) 
{
    return FieldHelper(Test, IntToType()).tValue;//结合 SValue 使用
}

template struct SValue 
{
    T tValue; 

protected:
    ~SValue(){}
};


//产生线性继承体系
template class CUnit,
    typename TRoot = SNullType>
class CLineCreate;

template class CUnit, typename TRoot>
class CLineCreate, CUnit, TRoot> : 
    public CUnit>
{
};

template class CUnit,
    typename TRoot>
class CLineCreate : public CUnit
{
};

template
class CData
{
public:
    virtual void Fun() {}
    virtual ~CData() {}
};

template
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::Result).name()
        //"float"
    };
    //typeid(STypeAt::Result).name();
    //error C2027: 使用了未定义类型“STypeAt”

    int nLen = SLength::nLength;
    //nLen = 4

    int aId[] = 
    {
        SFind::nId,   //0
        SFind::nId,//1
        SFind::nId, //2
        SFind::nId,  //-1
    };
    
    const char* aStr1[] =
    {
        typeid(SAppend::Type_NewType).name(),
        //"struct SNullType"

        typeid(SAppend::Type_NewType).name(),
        //"struct STypeList"

        typeid(SAppend::Type_NewType).name()
        //"struct STypeList >"
    };

    //元素全为true
    bool aRe[] =    
    {
        typeid(SAppend::Type_NewType)
            == typeid(STYPELIST_3(int, double, char)),

        typeid(SErase
            ::Type_NewType) == typeid(STYPELIST_3(int, char, double)),
        typeid(SEraseAll::
            Type_NewType) == typeid(STYPELIST_2(int, char)),

        typeid(SNoDumplicate::
            Type_NewType) == typeid(STYPELIST_3(int, double, char)),

        typeid(SReplace::Type_NewType) == typeid(STYPELIST_4(int, long, char, 
            double)),
        typeid(SReplaceAll::Type_NewType) == typeid(STYPELIST_4(int, long, char, 
            long))
    };

    const char* pStr = typeid
        (SMostDerived::Type_NewType).name();
    //"class CF"

    bool nRe = typeid(SDerivedToFront
        ::Type_NewType) == typeid(STYPELIST_4(CF, CC, CCC, CF));
    //nRe = true

    CTest Test;
    /*
    输出:
    int
    bool
    double
    SNullType
    struct STypeList
    struct STypeList>
    struct STypeList>>
    */

    /*
    Test对象的继承的基类:
    SValue
    SValue
    SValue          

    CTest
    CTest
    CTest
    CTest

    CTest,SValue>
    CTest>,SValue>
    */

    (static_cast&>(Test)).tValue = 0;
    (static_cast&>(Test)).tValue = 0.1;
    Field(Test).tValue = true;

    CTest Test1;
    //warning C4584: “CTest”: 
    //      基类“CTest”已是“CTest”的基类
    //Field(Test1).tValue = 1;
    //error C2594: “return”: 从“CTest”到“SValue &”的转换不明确

    Field<1>(Test1).tValue = 1; //第二个int成功被置为1

    //自己实现tuple
    CTest Test2;
    MyGet<0>(Test2) = 1;
    MyGet<1>(Test2) = 2;
    MyGet<2>(Test2) = 1.1;
    MyGet<3>(Test2) = true;
    //Test2 中对应值均正确

    CTest Data;
    int nSize = sizeof Data;    //nSize = 12 虚函数导致的开销 Win32环境
    //Data对象的基类中的CData,CData,CData具有虚函数
    CLineCreate Data1;
    int nSize1 = sizeof Data1;  //nSize1 = 4

    /*
    Data1对象的继承基类
    CData1
    CLineCreate,CData1,CBase>
    CData1,CData1,CBase> >
    CLineCreate >,CData1,CBase>
    CData1 >,
        CData1,CBase> >
    */

    return 0;
}

你可能感兴趣的:(第三章 Typelists)