TypeSwitch

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);
    }
 }

Utilities

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.