📄 hierarchygenerators.h
字号:
////////////////////////////////////////////////////////////////////////////////
// helper class template FieldHelper
// See Field below
////////////////////////////////////////////////////////////////////////////////
template <unsigned int i>
struct FieldHelper
{
template<class H, class Unit>
struct In
{
private:
typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
typedef typename ApplyInnerType<Unit, ElementType>::type UnitType;
enum { isConst = TypeTraits<H>::isConst };
typedef typename Select
<
isConst,
const typename H::RightBase,
typename H::RightBase
>
::Result RightBase;
typedef typename Select
<
IsEqualType<UnitType, TupleUnit<ElementType> >::value,
ElementType,
UnitType
>
::Result UnqualifiedResultType;
public:
typedef typename Select
<
isConst,
const UnqualifiedResultType,
UnqualifiedResultType
>
::Result ResultType;
// Must be a template, don't know why.
// If Do is not a template and H& is used as parameter
// MSVC will give a linker error.
template <class T>
static ResultType& Do(H& obj, T*)
{
//typedef typename T::RightBase RightBase;
//RightBase& rightBase = obj;
RightBase& rightBase = obj;
return FieldHelper<i - 1>::template In<RightBase, Unit>::Do(rightBase, (int*)0);
}
};
};
template <>
struct FieldHelper<0>
{
template<class H, class Unit>
struct In
{
private:
typedef typename H::TList::Head ElementType;
typedef typename ApplyInnerType<Unit, ElementType>::type UnitType;
enum { isConst = TypeTraits<H>::isConst };
typedef typename Select
<
isConst,
const typename H::LeftBase,
typename H::LeftBase
>
::Result LeftBase;
typedef typename Select
<
IsEqualType<UnitType, TupleUnit<ElementType> >::value,
ElementType,
UnitType
>
::Result UnqualifiedResultType;
public:
typedef typename Select
<
isConst,
const UnqualifiedResultType,
UnqualifiedResultType
>
::Result ResultType;
public:
template <class T>
static ResultType& Do(H& obj, T*)
{
LeftBase& leftBase = obj;
return leftBase;
}
};
};
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
// i is the index of a type in the typelist used to generate H):
// Field<i>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
// and T is the i-th type in the typelist
////////////////////////////////////////////////////////////////////////////////
/*
template <unsigned int i, class TList, class UnitWrapper>
typename FieldHelper<i>::template In<GenScatterHierarchy<TList, UnitWrapper>,UnitWrapper>::ResultType&
Field(GenScatterHierarchy<TList, UnitWrapper>& obj, Int2Type<i>)
{
typedef typename GenScatterHierarchy<TList, UnitWrapper> H;
return FieldHelper<i>::template In<H, UnitWrapper>::Do(obj, (int*)0);
}
*/
template <unsigned int i, class TList, class UnitWrapper>
typename FieldHelper<i>::template In<GenScatterHierarchy<TList, UnitWrapper>,UnitWrapper>::ResultType&
Field(GenScatterHierarchy<TList, UnitWrapper>& obj, Int2Type<i>* = (Int2Type<i>*)0)
{
typedef typename GenScatterHierarchy<TList, UnitWrapper> H;
return FieldHelper<i>::template In<H, UnitWrapper>::Do(obj, (int*)0);
}
////////////////////////////////////////////////////////////////////////////////
// class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Model is a template of two args):
// GenScatterHierarchy<TList, Model>
////////////////////////////////////////////////////////////////////////////////
// VC 6.0 changes:
// see GenScatterHierarchy
template
<
class TList,
class Unit,
class Root = EmptyType
>
class GenLinearHierarchy;
namespace Private
{
template <typename TListTag>
struct GenLinearHierarchyHelper
{
template<class TList, class Unit, class Root>
struct In
{
typedef typename TList::ERROR_THIS_INSTANCE_SELECTED Result;
};
};
template <>
struct GenLinearHierarchyHelper<TL::Private::Typelist_tag>
{
template<class TList, class Unit, class Root>
struct In
{
private:
typedef typename TList::Head Head;
typedef typename TList::Tail Tail;
public:
typedef typename
ApplyInnerType2<Unit, Head, GenLinearHierarchy<Tail, Unit, Root> >::type Result;
};
};
template <>
struct GenLinearHierarchyHelper<TL::Private::NullType_tag>
{
template<class TList, class Unit, class Root>
struct In
{
private:
typedef typename TList::Head Head;
public:
typedef typename ApplyInnerType2<Unit,Head, Root>::type Result;
};
};
template <class T, class U, class Root>
struct Wrap
{
struct Dummy {};
typedef typename T::Tail Tail;
// create the hierarchy
typedef typename Private::GenLinearHierarchyHelper
<
typename TL::Private::IsTypelist<Tail>::type_tag
>
::template In<T, U, Root>::Result TempType;
typedef Private::VC_Base_Workaround<TempType, Dummy> type;
// this is nothing more than a typedef to the created hierarchy (TempType).
// But if we try to inherit directly from TempType VC 6.0
// will produce a "Error C2516. : is not a legal base class."
typedef typename type::LeftBase Base;
};
} // namespace Private
// Trying to inherit from LinBase will result in "Error C2516. : is not a legal base class."
// Private::Wrap introduces some levels of indirections which will
// make the vc happy.
template
<
class TList,
class Unit,
class Root
>
class GenLinearHierarchy : public Private::Wrap<TList, Unit, Root>::Base
{
ASSERT_TYPELIST(TList); // TList must not be NullType
public:
typedef typename Private::GenLinearHierarchyHelper
<
typename TL::Private::IsTypelist<typename TList::Tail>::type_tag
>
::template In<TList, Unit, Root>::Result LinBase;
};
} // namespace Loki
#if defined (_MSC_VER) && _MSC_VER <= 1300
#define FIELD(Obj, Nr) \
Field(Obj, (Int2Type<Nr>*)0)
#else
#define FIELD(Obj, Nr) \
Field<Nr>(Obj)
#endif
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// September 16, 2002: Fixed dependent template, using "::template" syntax. T.S.
// Oct 24, 2002: ported by Benjamin Kaufmann to MSVC 6
// Dec 08, 2002: Fixed problems with MSVC6-Version of GenScatterHierarchy when
// used with typelists containing equal types. B.K.
// New Version is ugly :-(
// Dec 08, 2002: Interface changed for Field-Function. The old version does not
// work correctly due to the "Explicitly Specified Template
// Functions Not Overloaded Correctly"-Bug
// (Microsoft KB Article - 240871). B.K.
// Mar 08, 2003: New transparent workaround for Field-Functions. The FIELD-Macro
// is no longer needed. B.K.
////////////////////////////////////////////////////////////////////////////////
#undef IS_TYPELIST
#endif // HIERARCHYGENERATORS_INC_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -