Files CCore/inc/TypeSwitch.h CCore/src/TypeSwitch.cpp
TypeSwitch lives in the namespace Meta. It is an advanced meta-tool to build switches based on a given integer-to-type mapping.
To specify a single map the type Meta::Case is used.
template <class SUInt,SUInt Val,class T> struct Meta::Case;
To define a mapping the type Meta::CaseList is used.
template <class ... CC> struct Meta::CaseList.
It is assumed that template parameters here are some Meta::Cases with the same type SUInt and distinct values Val. For example:
using MyCaseList = Meta::CaseList< Meta::Case<int,1,T1> , Meta::Case<int,2,T2> , Meta::Case<int,3,T3> > ; // // 1 -> T1 // 2 -> T2 // 3 -> T3 //
Once you have some case list you may generate a switch, using the type Meta::TypeSwitch:
template <class CaseList> struct Meta::TypeSwitch;
Namely:
template <class CaseList>
struct Meta::TypeSwitch
{
using SwType = .... ;
template <class Ctx,class RetType=typename Ctx::RetType>
static RetType Switch(SwType val,Ctx ctx);
};
SwType here is the common SUInt type from the Meta::Cases.
The template parameter Ctx must comply with the following pattern:
struct Ctx { .... using RetType = .... ; template <class T> RetType call(); RetType defcall(SwType val); };
Assume, the input case list is Meta::CaseList< Meta::Case<int,1,T1> , Meta::Case<int,2,T2> , Meta::Case<int,3,T3> >. The generated method Switch does the following:
RetType Switch(SwType val,Ctx ctx) { switch( val ) { case 1 : return ctx.template call<T1>(); case 2 : return ctx.template call<T2>(); case 3 : return ctx.template call<T3>(); default: return ctx.defcall(val); } }
There are several utilities to work with case lists.
template <class Case>
using Meta::CaseType = .... ;
//
// Meta::CaseType< Meta::Case<SUInt,Val,T> > == T
//
This Meta-type extracts the type from the Case.
template <class CaseList,class T>
const auto Meta::CaseVal = .... ;
//
// Meta::CaseVal< Meta::CaseList< .... Meta::Case<SUInt,Val,T> .... > , T > == Val
//
This Meta-constant returns the value, associated with the given type in the given case-list.
template <class CaseList>
const ulen Meta::CaseListMaxSizeof = .... ;
//
// Meta::CaseListMaxSizeof< Meta::CaseList< .... Meta::Case<SUInt,Val,T> .... > > == Meta::MaxOf( sizeof(T) ... )
//
This Meta-constant returns the maximum sizeof of types in the given case-list.