loki库是C++模板大牛Andrei写的, 里面大量运用模板的特性, 而tc_loki.h借用了loki库的部分代码, 形成了一个基本的文件tc_loki.h, 来看看:
#ifndef __TC_TYPETRAITS_H
#define __TC_TYPETRAITS_H
#include
namespace tars
{
/////////////////////////////////////////////////
// 说明: loki
/////////////////////////////////////////////////
namespace TL
{
//只声明, 不定义的类, 作为TYPELIST的末端类型
class NullType;
//空类型
struct EmptyType { };
/**
* 数值到类型的映射
*/
template
struct Int2Type
{
enum { value = v };
};
/**
* 类型到类型的映射
*/
template
struct Type2Type
{
typedef T OriginalType;
};
///////////////////////////////////////////////////////////////////////////
// 以下是TypeList的定义(目前只支持10个参数)
/**
* 定义类型链表
*/
template
struct TypeList
{
typedef Head H;
typedef Tail T;
};
#define TYPELIST_1(T1) TypeList
#define TYPELIST_2(T1, T2) TypeList
#define TYPELIST_3(T1, T2, T3) TypeList
#define TYPELIST_4(T1, T2, T3, T4) TypeList
#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList
#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) TypeList
#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) TypeList
#define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) TypeList
#define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) TypeList
#define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) TypeList
#define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) TypeList
#define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) TypeList
#define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) TypeList
#define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) TypeList
#define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) TypeList
#define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) TypeList
#define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) TypeList
#define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) TypeList
#define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) TypeList
//////////////////////////////////////////////////////////////////////////////
// 以下定义TypeList的编译期的操作函数(通过偏特化实现)
/**
* Length: 取TypeList的长度
*/
template struct Length;
template<> struct Length
{
enum { value = 0 };
};
template struct Length >
{
enum { value = 1 + Length::value };
};
/**
* TypeAt, 取链表在i位置上的类型
*/
template struct TypeAt;
template struct TypeAt, 0>
{
typedef Head Result;
};
template struct TypeAt, i>
{
typedef typename TypeAt::Result Result;
};
/**
* TypeAt, 取链表在i位置上的类型, i超出了返回, 则返回DefaultType
*/
template struct TypeAtNonStrict
{
typedef DefaultType Result;
};
template struct TypeAtNonStrict, 0, DefaultType>
{
typedef Head Result;
};
template struct TypeAtNonStrict, i, DefaultType>
{
typedef typename TypeAtNonStrict::Result Result;
};
/**
* 取链表上类型为T的序号, 没有则返回-1
*/
template struct IndexOf;
template struct IndexOf
{
enum { value = -1 };
};
template struct IndexOf, T>
{
enum { value = 0 };
};
template struct IndexOf, T>
{
private:
enum { temp = IndexOf::value };
public:
enum { value = temp == -1 ? -1 : 1 + temp };
};
/**
* Append, 添加到链表尾部
*/
template struct Append;
template<> struct Append
{
typedef NullType Result;
};
template struct Append
{
typedef TYPELIST_1(T) Result;
};
template struct Append >
{
typedef TypeList Result;
};
template struct Append, T>
{
typedef TypeList::Result> Result;
};
/**
* Erase 删除
*/
template struct Erase;
template struct Erase
{
typedef NullType Result;
};
template struct Erase, T>
{
typedef Tail Result;
};
template struct Erase, T>
{
typedef TypeList::Result> Result;
};
/**
* EraseAll 删除
*/
template struct EraseAll;
template struct EraseAll
{
typedef NullType Result;
};
template struct EraseAll, T>
{
typedef typename EraseAll::Result Result;
};
template struct EraseAll, T>
{
typedef TypeList::Result> Result;
};
/**
* 生成TypeList类型
*/
template
struct TLMaker
{
private:
typedef TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) TmpList;
public:
typedef typename EraseAll::Result Result;
};
/////////////////////////////////////////////////////////////////////////////////////
//判断类型T是否可以转换成类型U(参考了wbl库, 直接采用loki, 编译时会有警告
//关键:如果能够转换, 则接收U的函数, 也能够接收T
template
class Conversion
{
protected:
typedef char YES;
struct NO {char dummy[2];};
struct any_conversion
{
template any_conversion(const volatile P&);
template any_conversion(P&);
};
template struct conversion_checker
{
static NO _m_check(any_conversion ...);
static YES _m_check(P, int);
};
static T _m_from;
public:
enum
{
//是否可以转换(如果Test(makeT())匹配到了static Small Test(U), 则可以转换)
exists = (sizeof(conversion_checker::_m_check(_m_from, 0)) == sizeof(YES)),
//是否可以双向转换
exists2Way = exists && Conversion::exists,
//是否相同类型
sameType = false
};
};
//偏特化来确定sameType
template
class Conversion
{
public:
enum
{
exists = true,
exists2Way = true,
sameType = true
};
};
//判断两个类是否可以继承
//关键:子类指针可以转换成父类指针, 且不是void*类型
//相同类型, SUPERSUBCLASS判断为true
#define SUPERSUBCLASS(T, U) (TL::Conversion::exists && !TL::Conversion::sameType)
//相同类型, SUPERSUBCLASS_STRICT判断为false
#define SUPERSUBCLASS_STRICT(T, U) (SUPERSUBCLASS(T, U) && !TL::Conversion::sameType)
///////////////////////////////////////////////////////////////////////////////////////////////
// 类型选择器
template
struct TypeSelect
{
typedef U Result;
};
template
struct TypeSelect
{
typedef V Result;
};
///////////////////////////////////////////////////////////////////////////////////////
/**
* 类型萃取器, copy至Loki库
*/
template
class TypeTraits
{
private:
///////////////////////////////////////////////////////
//提取引用的原始类型(即去掉引用类型)
template
struct ReferenceTraits
{
enum { result = false };
typedef U Result;
};
template
struct ReferenceTraits
{
enum { result = true };
typedef U Result;
};
///////////////////////////////////////////////////////
//指针类型
template
struct PointerTraits
{
enum { result = false };
typedef TL::NullType Result;
};
template
struct PointerTraits
{
enum { result = true };
typedef U Result;
};
template
struct PointerTraits
{
enum { result = true };
typedef U Result;
};
///////////////////////////////////////////////////////
//成员函数指针, gcc下面支持有问题, 屏蔽之
template
struct PointerToMemberTraits
{
enum { result = false };
};
template
struct PointerToMemberTraits
{
enum { result = true };
};
template
struct PointerToMemberTraits
{
enum { result = true };
};
///////////////////////////////////////////////////////
// const
template
struct UnConstTraits
{
enum { result = false };
typedef U Result;
};
template
struct UnConstTraits
{
enum { result = true };
typedef U Result;
};
template
struct UnConstTraits
{
enum { result = true };
typedef U& Result;
};
///////////////////////////////////////////////////////
// volatile
template
struct UnVolatileTraits
{
enum { result = false };
typedef U Result;
};
template
struct UnVolatileTraits
{
enum { result = true };
typedef U Result;
};
template
struct UnVolatileTraits
{
enum { result = true };
typedef U& Result;
};
public:
//T是否是指针类型
enum { isPointer = PointerTraits::result };
//T是否是引用类型
enum { isReference = ReferenceTraits::result };
//T是否指向成员函数的指针
enum { isMemberPointer = PointerToMemberTraits::result };
//T是否是Const类型
enum { isConst = UnConstTraits::result };
//T是否是Volatile类型
enum { isVolatile = UnVolatileTraits::result };
//如果T是指针类型,则获取T的原类型, 即去掉指针类型
typedef typename PointerTraits::Result PointeeType;
//如果T是引用类型,则获取T的原类型, 即去掉引用类型
typedef typename ReferenceTraits::Result ReferencedType;
//如果T是Const类型,则获取T的原类型, 即去掉Const类型
typedef typename UnConstTraits::Result NonConstType;
//如果T是volatile类型,则获取T的原类型, 即去掉volatile类型
typedef typename UnVolatileTraits::Result NonVolatileType;
//去掉const volatile类型
typedef typename UnVolatileTraits::Result>::Result UnqualifiedType;
public:
//////////////////////////////////////////////////////
//
typedef TL::TLMaker::Result UnsignedInts;
typedef TL::TLMaker::Result SignedInts;
typedef TL::TLMaker::Result OtherInts;
typedef TL::TLMaker::Result Floats;
typedef TL::TYPELIST_2(TL::EmptyType, TL::NullType) NullTypes;
//无符号整形
enum { isStdUnsignedInt = TL::IndexOf::value >= 0 };
//有符号整形
enum { isStdSignedInt = TL::IndexOf::value >= 0 };
//整形
enum { isStdInt = isStdUnsignedInt || isStdSignedInt || TL::IndexOf::value >= 0 };
//浮点类型
enum { isStdFloat = TL::IndexOf::value >= 0 };
//数值类型
enum { isStdArith = isStdInt || isStdFloat };
//基础类型(包括void)
enum { isStdFundamental = isStdArith || TL::IndexOf::value >= 0};
//空类型
enum { isNullType = TL::IndexOf::value >= 0 };
//简单类型
enum { isBaseType = isStdArith || isPointer || isMemberPointer };
//对于复杂类型, 获取数据的引用类型, 即加上引用类型
typedef typename TypeSelect::Result ReferenceType;
//对于复杂类型且非空类型, 获取数据的引用类型, 即加上引用类型
//typedef typename TypeSelect::Result ReferenceTypeEx;
//获取数据的原类型, 消除引用的引用这种情况
typedef typename TypeSelect::Result ParameterType;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//下面的使用开始展示TypeList的威力, 用于自动生成class
//散乱的继承体系
template class Unit>
class ScatterHierarchy;
/*
namespace p
{
//注释copy至loki库
// The following type helps to overcome subtle flaw in the original
// implementation of GenScatterHierarchy.
// The flaw is revealed when the input type list of GenScatterHierarchy
// contains more then tars element of the same type (e.g. LOKI_TYPELIST_2(int, int)).
// In this case GenScatterHierarchy will contain multiple bases of the same
// type and some of them will not be reachable (per 10.3).
// For example before the fix the first element of Tuple
// is not reachable in any way!
template
struct ScatterHierarchyTag;
}
template class Unit>
class ScatterHierarchy, Unit> : public ScatterHierarchy, Unit>
, public ScatterHierarchy
{
public:
typedef TypeList TList;
typedef ScatterHierarchy, Unit> LeftBase;
typedef ScatterHierarchy RightBase;
template struct Rebind
{
typedef Unit Result;
};
};
// In the middle *unique* class that resolve possible ambiguity
template class Unit>
class ScatterHierarchy, Unit>
: public ScatterHierarchy
{
};
*/
//具现化继承体系
template class Unit>
class ScatterHierarchy, Unit>
: public ScatterHierarchy
, public ScatterHierarchy
{
public:
typedef TypeList TList;
typedef ScatterHierarchy LeftBase;
typedef ScatterHierarchy RightBase;
template struct Rebind
{
typedef Unit Result;
};
};
template class Unit>
class ScatterHierarchy : public Unit
{
public:
typedef Unit LeftBase;
template struct Rebind
{
typedef Unit Result;
};
};
template class Unit>
class ScatterHierarchy
{
public:
template struct Rebind
{
typedef Unit Result;
};
};
/////////////////////////////////////////////////////////////////////
//构建继承体系后, 采用下面的函数获取继承体系中某个类
template
struct FieldHelperByType
{
typedef typename H::template Rebind::Result ResultType;
static ResultType& dochange(H &obj)
{
return static_cast(obj);
}
};
template
struct FieldHelperByType
{
typedef const typename H::template Rebind::Result ResultType;
static ResultType& dochange(const H &obj)
{
return (ResultType&)obj;
}
};
//直接按照类型获取, 如果有两个相同的类型, 则编译不过
template
typename FieldHelperByType::ResultType& field(H &obj)
{
return FieldHelperByType::dochange(obj);
}
/////////////////////////////////////////////////////////////////////
// 根据索引获取字段
//定义Tuple, 默认的数据操作器(Unit)
template
struct TupleUnit
{
T _value;
operator T&() { return _value; }
operator const T&() const { return _value; }
};
template
struct Tuple : public ScatterHierarchy
{
};
//定义FieldHelperByIndex
template struct FieldHelperByIndex;
//特化版本的FieldHelperByIndex, 推导出最后一个元素
template
struct FieldHelperByIndex
{
typedef typename H::TList::H ElementType;
typedef typename H::template Rebind::Result UnitType;
enum
{
isTuple = Conversion >::sameType,
isConst = TypeTraits::isConst
};
typedef const typename H::LeftBase ConstLeftBase;
typedef typename TypeSelect::Result LeftBase;
typedef typename TypeSelect::Result UnqualifiedResultType;
typedef typename TypeSelect::Result ResultType;
static ResultType &dochange(H& obj)
{
LeftBase &leftBase = obj;
return (ResultType&)leftBase;
}
};
//根据索引获取FieldHelper
template
struct FieldHelperByIndex
{
typedef typename TypeAt::Result ElementType;
typedef typename H::template Rebind::Result UnitType;
enum
{
isTuple = Conversion >::sameType,
isConst = TypeTraits::isConst
};
typedef const typename H::RightBase ConstRightBase;
typedef typename TypeSelect::Result RightBase;
typedef typename TypeSelect::Result UnqualifiedResultType;
typedef typename TypeSelect::Result ResultType;
static ResultType &dochange(H& obj)
{
RightBase &rightBase = obj;
return FieldHelperByIndex::dochange(rightBase);
}
};
//定义按照索引获取
template
typename FieldHelperByIndex::ResultType &field(H& obj)
{
return FieldHelperByIndex::dochange(obj);
}
}
}
#endif
是不是有一种看天书的感觉, 确实如此。
也行, 姑且把它当成和STL类似的基础库, 别纠结于它。