metaprogramming.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_METAPROGRAMMING
00003 #define OPENGM_METAPROGRAMMING
00004 
00005 #include <limits>
00006 #include <vector>
00007 
00008 #include "opengm/datastructures/marray/marray.hxx"
00009 
00011 #define OPENGM_TYPELIST_1(T1) \
00012 ::opengm::meta::TypeList<T1, opengm::meta::ListEnd >
00013 
00014 #define OPENGM_TYPELIST_2(T1, T2) \
00015 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_1(T2) >
00016 
00017 #define OPENGM_TYPELIST_3(T1, T2, T3) \
00018 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_2(T2, T3) >
00019 
00020 #define OPENGM_TYPELIST_4(T1, T2, T3, T4) \
00021 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_3(T2, T3, T4) >
00022 
00023 #define OPENGM_TYPELIST_5(T1, T2, T3, T4, T5) \
00024 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_4(T2, T3, T4, T5) >
00025 
00026 #define OPENGM_TYPELIST_6(T1, T2, T3, T4, T5, T6) \
00027 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_5(T2, T3, T4, T5, T6) >
00028 
00029 #define OPENGM_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
00030 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_6(T2, T3, T4, T5, T6, T7) >
00031 
00032 #define OPENGM_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
00033 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
00034 
00035 #define OPENGM_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
00036 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
00037 
00038 #define OPENGM_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
00039 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
00040 
00042 
00043 namespace opengm {
00044 
00045    template<class T>
00046    class Factor;
00047    template<class T,class I,class L>
00048    class IndependentFactor;
00049    
00051    namespace meta {
00053       template< template < typename > class TO_BIND >
00054       struct Bind1{
00055          template<class BIND_ARG_0>
00056          struct Bind{
00057             typedef TO_BIND<BIND_ARG_0> type;
00058          };
00059       };
00061       template< template < typename ,typename > class TO_BIND >
00062       struct Bind2{
00063          template<class BIND_ARG_0, class BIND_ARG_1>
00064          struct Bind{
00065             typedef TO_BIND<BIND_ARG_0, BIND_ARG_1> type;
00066          };
00067       };
00069       template< template < typename ,typename, typename > class TO_BIND >
00070       struct Bind3{
00071          template<class BIND_ARG_0, class BIND_ARG_1, class BIND_ARG_2>
00072          struct Bind{
00073             typedef TO_BIND<BIND_ARG_0, BIND_ARG_1, BIND_ARG_2> type;
00074          };
00075       };
00076 
00082       template<class T>
00083       struct ApplyMetaFunction {
00084          typedef typename T::type type;
00085       };
00089       template<class T>
00090       struct Self {
00091          typedef T type;
00092       };
00094       struct EmptyType {
00095       };
00097       struct NullType {
00098       };
00100       struct ListEnd {
00101       };
00103       struct True {
00104 
00105          enum Value {
00106             value = 1
00107          };
00108       };
00110       struct False {
00111 
00112          enum Value {
00113             value = 0
00114          };
00115       };
00116 
00118       struct TrueCase {
00119 
00120          enum Value {
00121             value = 1
00122          };
00123          typedef meta::True type;
00124       };
00126       struct FalseCase {
00127 
00128          enum Values {
00129             value = 0
00130          };
00131          typedef meta::False type;
00132       };
00134       template<int N>
00135       struct Int {
00136 
00137          enum Value {
00138             value = N
00139          };
00140       };
00142       template<size_t N>
00143       struct SizeT {
00144 
00145          enum Value {
00146             value = N
00147          };
00148       };
00150       template < bool T_BOOL> struct Bool;
00152       template < > struct Bool < true > : meta::TrueCase {
00153       };
00155       template < > struct Bool < false > : meta::FalseCase {
00156       };
00158       template<bool T_BOOL_A, bool T_BOOL_B>
00159       struct Or;
00161       template < > struct Or < true, true > : meta::TrueCase {
00162       };
00164       template < > struct Or < true, false > : meta::TrueCase {
00165       };
00167       template < > struct Or < false, true > : meta::TrueCase {
00168       };
00170       template < > struct Or < false, false > : meta::FalseCase {
00171       };
00173       template<bool T_BOOL>
00174       struct Not;
00176       template<>
00177       struct Not<true> : meta::FalseCase {
00178       };
00180       template<>
00181       struct Not<false> : meta::TrueCase {
00182       };
00184       template<bool T_BOOL_A, bool T_BOOL_B>
00185       struct And;
00187       template < > struct And < true, true > : meta::TrueCase {
00188       };
00190       template < > struct And < true, false > : meta::FalseCase {
00191       };
00193       template < > struct And < false, true > : meta::FalseCase {
00194       };
00196       template < > struct And < false, false > : meta::FalseCase {
00197       };
00199       template<bool T_Bool, class T_True, class T_False>
00200       struct If;
00202       template<class T_True, class T_False>
00203       struct If < true, T_True, T_False> {
00204          typedef T_True type;
00205       };
00207       template<class T_True, class T_False>
00208       struct If < false, T_True, T_False> {
00209          typedef T_False type;
00210       };
00212       template<bool T_Bool, class MetaFunctionTrue, class MetaFunctionFalse>
00213       struct EvalIf : public meta::If<T_Bool, MetaFunctionTrue, MetaFunctionFalse>::type {
00214       };
00216       template<size_t  I>
00217       struct Decrement{
00218          typedef SizeT< I-1 > type;
00219          enum Values{
00220             value=I-1
00221          };
00222       };
00224       template<size_t  I>
00225       struct Increment{
00226          typedef SizeT< I+1 > type;
00227          enum Values{
00228             value=I+1
00229          };
00230       };
00232       #define OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO(OPERATOR_SYMBOL,CLASS_NAME,RETURN_CLASS_TYPE) \
00233       template<size_t A,size_t B> \
00234       struct CLASS_NAME{ \
00235          typedef typename Bool< (A OPERATOR_SYMBOL B) >::type type; \
00236          enum Values{ \
00237             value=RETURN_CLASS_TYPE < (A OPERATOR_SYMBOL B) >::value \
00238          }; \
00239       }
00240 
00242       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( +  , Plus ,                 meta::SizeT );
00244       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( -  , Minus ,                meta::SizeT );
00246       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( *  , Multiplies ,           meta::SizeT );
00248       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( == , EqualNumber ,          meta::Bool );
00250       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( >  , BiggerNumber ,         meta::Bool );
00252       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( >= , BiggerOrEqualNumber ,  meta::Bool );
00254       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( <  , SmallerNumber ,        meta::Bool );
00256       OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( <= , SmallerOrEqualNumber , meta::Bool );
00258       template< size_t A,size_t B>
00259       struct MinimumNumber{
00260          enum Value{
00261             value= meta::If<
00262                SmallerNumber<A,B>::value,
00263                SizeT<A>,
00264                SizeT<B>
00265             >::type::value
00266          };
00267       };
00268       
00270       template<class T, class U>
00271       struct Compare : FalseCase {
00272       };
00274       template<class T>
00275       struct Compare<T, T> : TrueCase {
00276       };
00278       template<class T>
00279       struct InvalidType {
00280          typedef T type;
00281       };
00283       template<class T>
00284       struct IsInvalidType: opengm::meta::FalseCase {
00285       };
00287       template<class T>
00288       struct IsInvalidType< InvalidType< T > > : opengm::meta::TrueCase {
00289       };
00290 
00292       template<class T>
00293       struct IsFactor : meta::FalseCase {
00294       };
00296       template<class T>
00297       struct IsFactor<opengm::Factor<T> > :  opengm::meta::TrueCase {
00298       };
00299 
00301       template<class T>
00302       struct IsIndependentFactor :  opengm::meta::FalseCase {
00303       };
00305       template<class T,class I,class L>
00306       struct IsIndependentFactor<opengm::IndependentFactor<T,I,L> > : opengm::meta::TrueCase {
00307       };
00309       template<class T>struct IsVoid : meta::FalseCase {
00310       };
00312       template< > struct IsVoid<void> : meta::TrueCase {
00313       };
00315       template<class T> struct IsReference : meta::FalseCase {
00316       };
00318       template<class T> struct IsReference<const T &> : meta::FalseCase {
00319       };
00321       template<class T> struct IsReference<T&> : meta::TrueCase {
00322       };
00324       template<class T> struct IsConstReference : meta::FalseCase {
00325       };
00327       template<class T> struct IsConstReference< T &> : meta::FalseCase {
00328       };
00330       template<class T> struct IsConstReference<const T&> : meta::TrueCase {
00331       };
00333       template <typename T>
00334       struct RemoveReference {
00335          typedef T type;
00336       };
00338       template <typename T>
00339       struct RemoveReference<T&> {
00340          typedef T type;
00341       };
00343       template <typename T>
00344       struct RemoveConst {
00345          typedef T type;
00346       };
00348       template <typename T>
00349       struct RemoveConst<const T> {
00350          typedef T type;
00351       };
00353       template<class T> struct AddReference {
00354          typedef typename meta::If <
00355             meta::Or <
00356             meta::IsReference<T>::value,
00357             meta::IsConstReference<T>::value
00358             >::value,
00359             T,
00360             T &
00361             >::type type;
00362       };
00364       template<class T> struct AddConstReference {
00365          typedef typename meta::If
00366             <
00367             meta::IsConstReference<T>::value,
00368             T,
00369             typename meta::If <
00370             meta::IsReference<T>::value,
00371             typename meta::RemoveReference<T>::type const &,
00372             T const &
00373             >::type
00374             >::type type;
00375       };
00377       template<class T_List>
00378       struct LengthOfTypeList {
00379          typedef meta::Int < 1 + LengthOfTypeList<typename T_List::TailType>::type::value> type;
00380          enum {
00381             value = type::value
00382          };
00383       };
00385       template< >
00386       struct LengthOfTypeList<meta::ListEnd> {
00387          typedef meta::Int < 0 > type;
00388 
00389          enum {
00390             value = 0
00391          };
00392       };
00394       template<class T_List, unsigned int Index>
00395       struct TypeAtTypeList {
00396          typedef typename TypeAtTypeList<typename T_List::TailType, Index - 1 > ::type type;
00397       };
00399       template<class T_List>
00400       struct TypeAtTypeList<T_List, 0 > {
00401          typedef typename T_List::HeadType type;
00402       };
00404       template<class T_List, unsigned int Index, class T_DefaultType>
00405       struct TypeAtTypeListSave
00406       : meta::EvalIf<
00407          meta::LengthOfTypeList<T_List>::value >= Index ? true : false,
00408          meta::TypeAtTypeList<T_List, Index>,
00409          meta::Self<T_DefaultType>
00410       >::type {
00411       };
00412       
00414       template<class T_Head, class T_Tail>
00415       struct TypeList {
00416          typedef meta::ListEnd ListEnd;
00417          typedef T_Head HeadType;
00418          typedef T_Tail TailType;
00419       };
00421       template
00422       <
00423       class T1,
00424       class T2 = opengm::meta::ListEnd,
00425       class T3 = opengm::meta::ListEnd,
00426       class T4 = opengm::meta::ListEnd,
00427       class T5 = opengm::meta::ListEnd,
00428       class T6 = opengm::meta::ListEnd,
00429       class T7 = opengm::meta::ListEnd,
00430       class T8 = opengm::meta::ListEnd,
00431       class T9 = opengm::meta::ListEnd,
00432       class T10 = opengm::meta::ListEnd,
00433       class T11 = opengm::meta::ListEnd,
00434       class T12 = opengm::meta::ListEnd,
00435       class T13 = opengm::meta::ListEnd,
00436       class T14 = opengm::meta::ListEnd,
00437       class T15 = opengm::meta::ListEnd
00438       >
00439       struct TypeListGenerator {
00440          typedef opengm::meta::TypeList<T1, typename TypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
00441       };
00443       template< >
00444       struct TypeListGenerator<opengm::meta::ListEnd> {
00445          typedef opengm::meta::ListEnd type;
00446       };
00447       
00449       template<bool B_IsTrue, class T_TrueType>
00450       struct SwitchCase {
00451          typedef T_TrueType type;
00452 
00453          struct Case : opengm::meta::Bool<B_IsTrue> {
00454          };
00455       };
00456 
00458       template <class T_List, class T_DefaultCase = opengm::meta::EmptyType >
00459       struct Switch {
00460          typedef typename opengm::meta::EvalIf
00461             <
00462             opengm::meta::TypeAtTypeList<T_List, 0 > ::type::Case::value,
00463             typename opengm::meta::TypeAtTypeList<T_List, 0 >::type,
00464             Switch<typename T_List::TailType, T_DefaultCase>
00465             >::type type;
00466       };
00468       template<class T_DefaultCase>
00469       struct Switch<opengm::meta::ListEnd, T_DefaultCase> {
00470          typedef T_DefaultCase type;
00471       };
00473       template<class T> struct IsPtr : opengm::meta::FalseCase {
00474       };
00476       template<class T> struct IsPtr<T * const> : opengm::meta::FalseCase {
00477       };
00479       template<class T> struct IsPtr<T * > : opengm::meta::TrueCase {
00480       };
00482       template<class T> struct IsConstPtr : opengm::meta::FalseCase {
00483       };
00485       template<class T> struct IsConstPtr<T * > : opengm::meta::FalseCase {
00486       };
00488       template<class T> struct IsConstPtr<T * const > : opengm::meta::TrueCase {
00489       };
00491       template<class T> struct IsConst : opengm::meta::FalseCase {
00492       };
00494       template<class T> struct IsConst< const T> : opengm::meta::TrueCase {
00495       };
00497       template<class T>
00498       struct IsFundamental {
00499          typedef typename opengm::meta::Or <
00500             std::numeric_limits< typename RemoveConst<T>::type >::is_specialized,
00501             opengm::meta::IsVoid< typename RemoveConst<T>::type >::value
00502             >::type type;
00503 
00504          enum Value{
00505             value = type::value
00506          };
00507       };
00509       template <class T>
00510       struct IsFloatingPoint :
00511       opengm::meta::Bool<
00512       opengm::meta::Compare<T, float >::value ||
00513       opengm::meta::Compare<T, const float >::value ||
00514       opengm::meta::Compare<T, double >::value ||
00515       opengm::meta::Compare<T, const double >::value ||
00516       opengm::meta::Compare<T, long double >::value ||
00517       opengm::meta::Compare<T, const long double >::value
00518       > {
00519       };
00521       template<class T>
00522       struct TypeInfo {
00523 
00524          struct IsFundamental : opengm::meta::IsFundamental<T> {
00525          };
00526 
00527          struct IsFloatingPoint : opengm::meta::IsFloatingPoint<T> {
00528          };
00529 
00530          struct IsConst : opengm::meta::IsConst<T> {
00531          };
00532 
00533          struct IsConstReference : opengm::meta::IsConstReference<T> {
00534          };
00535 
00536          struct IsReference : opengm::meta::IsReference<T> {
00537          };
00538 
00539          struct IsPtr : opengm::meta::IsPtr<T> {
00540          };
00541 
00542          struct IsConstPtr : opengm::meta::IsConstPtr<T> {
00543          };
00544       };
00546       template<class T>
00547       struct IsTypeList : meta::FalseCase{};
00549       template<class TH,class TT>
00550       struct IsTypeList< meta::TypeList<TH,TT> > : meta::TrueCase{};
00552       template<class T>
00553       struct TypeListFromMaybeTypeList{
00554          typedef meta::TypeList<T,meta::ListEnd> type;
00555       };
00557       template<class TH,class TT>
00558       struct TypeListFromMaybeTypeList< meta::TypeList<TH,TT> > {
00559          typedef meta::TypeList<TH,TT> type;
00560       };
00562       template<class TL,class FrontType>
00563       struct FrontInsert{
00564          typedef meta::TypeList<FrontType,TL> type;
00565       };
00567       template<class TL,class TYPE>
00568       struct BackInsert;
00570       template<class THEAD,class TTAIL,class TYPE>
00571       struct BackInsert<TypeList<THEAD,TTAIL> ,TYPE>{
00572          typedef TypeList<
00573             THEAD, 
00574             typename meta::BackInsert<
00575                TTAIL ,
00576                TYPE
00577             >::type 
00578          > type;
00579       };
00581       template<class TYPE>
00582       struct BackInsert<ListEnd,TYPE>{
00583          typedef meta::TypeList<TYPE,ListEnd> type;
00584       };
00586       template<class TL,class TypeToFindx>
00587       struct GetIndexInTypeList;
00589       template<class THEAD,class TTAIL,class TypeToFind>
00590       struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>{
00591          enum Value{
00592             value=GetIndexInTypeList<TTAIL,TypeToFind >::value+1
00593          };
00594          typedef meta::SizeT<GetIndexInTypeList<TTAIL,TypeToFind >::type::value +1> type;
00595       };
00597       template<class THEAD,class TTAIL>
00598       struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD >{
00599          enum Value{
00600             value=0
00601          };
00602          typedef meta::SizeT<0> type;
00603       };
00605       template<class TL,class TypeToFindx,size_t NOT_FOUND_INDEX>
00606       struct GetIndexInTypeListSafely;
00608       template<class THEAD,class TTAIL,class TypeToFind,size_t NOT_FOUND_INDEX>
00609       struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,TypeToFind,NOT_FOUND_INDEX>{
00610          enum Value{
00611             value=GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::value+1
00612          };
00613          typedef meta::SizeT<GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::type::value +1> type;
00614       };
00616       template<class THEAD,class TTAIL,size_t NOT_FOUND_INDEX>
00617       struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,THEAD,NOT_FOUND_INDEX >{
00618          enum Value{
00619             value=0
00620          };
00621          typedef meta::SizeT<0> type;
00622       };
00624       template<class TYPE_TO_FIND,size_t NOT_FOUND_INDEX>
00625       struct GetIndexInTypeListSafely<meta::ListEnd,TYPE_TO_FIND,NOT_FOUND_INDEX >{
00626          enum Value{
00627             value=NOT_FOUND_INDEX
00628          };
00629          typedef meta::SizeT<NOT_FOUND_INDEX> type;
00630       };
00632       template <class TL,class T>
00633       struct DeleteTypeInTypeList;
00635       template <class T>
00636       struct DeleteTypeInTypeList<ListEnd,T> {
00637          typedef ListEnd type;
00638       };
00640       template <class T,class TTail>
00641       struct DeleteTypeInTypeList<TypeList<T,TTail>,T> {
00642          typedef TTail type;
00643       };
00645       template <class THead,class TTail, class T>
00646       struct DeleteTypeInTypeList<TypeList<THead,TTail>,T> {
00647          typedef TypeList<THead, typename DeleteTypeInTypeList<TTail,T>::type> type;
00648       };
00650       template<class TL,class TypeToFindx>
00651       struct HasTypeInTypeList;
00653       template<class THEAD,class TTAIL,class TypeToFind>
00654       struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>
00655       {
00656          enum Value{
00657             value=HasTypeInTypeList<TTAIL,TypeToFind >::value
00658          };
00659          typedef HasTypeInTypeList< TTAIL,TypeToFind>  type;
00660       };
00661       
00663       template<class TL,class TSL,size_t SIZE,class NOT_FOUND>
00664       struct FindSizedType;
00666       template<class TLH,class TLT,class TSLH,class TSLT,size_t SIZE,class NOT_FOUND>
00667       struct FindSizedType<meta::TypeList<TLH,TLT>,meta::TypeList<TSLH,TSLT>,SIZE,NOT_FOUND>{
00668          typedef typename FindSizedType<TLT,TSLT,SIZE,NOT_FOUND >::type type;
00669       };
00671       template<class TLH ,class TLT,class TSLT,size_t SIZE,class NOT_FOUND>
00672       struct FindSizedType< meta::TypeList<TLH,TLT>,meta::TypeList< meta::SizeT<SIZE> ,TSLT>,SIZE,NOT_FOUND  >{
00673          typedef TLH type;
00674       };
00676       template<size_t SIZE,class NOT_FOUND>
00677       struct FindSizedType< meta::ListEnd,meta::ListEnd,SIZE,NOT_FOUND  >{
00678          typedef NOT_FOUND type;
00679       };
00681       template<class TL,class OTHER_TL>
00682       struct MergeTypeLists;
00684       template<class THEAD,class TTAIL,class OTHER_TL>
00685       struct MergeTypeLists<meta::TypeList<THEAD,TTAIL>,OTHER_TL>
00686       {
00687          typedef meta::TypeList< 
00688             THEAD,  
00689             typename MergeTypeLists<TTAIL,OTHER_TL>::type  
00690          >  type;
00691       };
00693       template<class OTHER_TL>
00694       struct MergeTypeLists<meta::ListEnd,OTHER_TL>
00695       {
00696          typedef OTHER_TL type;
00697       };
00699       template<class THEAD,class TTAIL>
00700       struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD > : meta::TrueCase{
00701       };
00703       template<class TypeToFindx>
00704       struct HasTypeInTypeList<meta::ListEnd,TypeToFindx> : meta::FalseCase{
00705       };
00710       template<class TL,class TYPE>
00711       struct InsertInTypeListOrMoveToEnd{
00712          typedef typename meta::If<
00713             meta::HasTypeInTypeList<
00714                TL,
00715                TYPE
00716             >::value,
00717             typename meta::BackInsert< 
00718                typename DeleteTypeInTypeList< TL,TYPE >::type,
00719                TYPE
00720             >::type,
00721             typename meta::BackInsert< 
00722                TL,
00723                TYPE
00724             >::type
00725          >::type type;
00726       };
00728       template<class TL>
00729       struct HasDuplicatesInTypeList;
00731       template<class THEAD,class TTAIL>
00732       struct HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >{
00733          typedef typename meta::EvalIf<
00734             HasTypeInTypeList<TTAIL,THEAD>::value,
00735             meta::Bool<true>,
00736             HasDuplicatesInTypeList< TTAIL>
00737          >::type type;
00738 
00739          enum Value{
00740             value= HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >::type::value
00741          };
00742       };
00744       template< >
00745       struct HasDuplicatesInTypeList<meta::ListEnd> : meta::FalseCase{
00746       };
00748       template<class MAYBE_TYPELIST,class EXPLICIT_FUNCTION_TYPE,bool EDITABLE>
00749       struct GenerateFunctionTypeList{
00750          typedef typename meta::TypeListFromMaybeTypeList<MAYBE_TYPELIST>::type StartTypeList;
00751          typedef typename meta::If<
00752             EDITABLE,
00753             typename InsertInTypeListOrMoveToEnd<StartTypeList,EXPLICIT_FUNCTION_TYPE>::type,
00754             StartTypeList
00755          >::type type;
00756          
00757       };
00759       template<class T>
00760       struct CallTraits {
00761          typedef T ValueType;
00762          typedef T value_type;
00763          typedef typename opengm::meta::AddReference<T>::type reference;
00764          typedef typename opengm::meta::AddConstReference<T>::type const_reference;
00765          typedef typename opengm::meta::If <
00766             opengm::meta::TypeInfo<T>::IsFundamental::value,
00767             typename opengm::meta::RemoveConst<T>::type const,
00768             typename opengm::meta::AddConstReference<T>::type
00769             >::type
00770             param_type;
00771       };
00773       template<class TList ,template <class> class InstanceUnitType,class TListSrc>
00774       class FieldHelper;
00775       template<class ListHead,class ListTail,template  <class> class InstanceUnitType,class TListSrc>
00776       class FieldHelper< opengm::meta::TypeList<ListHead,ListTail> ,InstanceUnitType,TListSrc>
00777       : public FieldHelper<ListHead,InstanceUnitType,TListSrc>,
00778         public FieldHelper<ListTail,InstanceUnitType,TListSrc>{
00779       };
00780       template< class ListTail ,template <class> class InstanceUnitType,class TListSrc>
00781       class FieldHelper
00782          : public InstanceUnitType<ListTail>{
00783       };
00784       template< template <class> class InstanceUnitType,class TListSrc>
00785       class FieldHelper<opengm::meta::ListEnd,InstanceUnitType,TListSrc>{
00786       };
00788       template<class TList ,template <class> class InstanceUnitType>
00789       class Field
00790       :  public FieldHelper<TList,InstanceUnitType,TList>{
00791       public:
00792          public:
00793          template <typename T>
00794          struct RebingByType{
00795                typedef InstanceUnitType<T> type;
00796            };
00797          template <size_t Index>
00798          struct RebingByIndex{
00799                typedef  InstanceUnitType<typename  TypeAtTypeList<TList,Index>::type > type;
00800            };
00801       };
00803       template<class TList ,class TYPE2,template <class ,class > class InstanceUnitType,class TListSrc>
00804       class Field2Helper;
00806       template<class ListHead,class ListTail,class TYPE2,template  <class,class> class InstanceUnitType,class TListSrc>
00807       class Field2Helper< opengm::meta::TypeList<ListHead,ListTail> ,TYPE2,InstanceUnitType,TListSrc>
00808       : public Field2Helper<ListHead,TYPE2,InstanceUnitType,TListSrc>,
00809         public Field2Helper<ListTail,TYPE2,InstanceUnitType,TListSrc>{
00810       };
00812       template< class ListTail ,class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
00813       class Field2Helper
00814       : public InstanceUnitType<ListTail,TYPE2>{
00815       };
00817       template< class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
00818       class Field2Helper<opengm::meta::ListEnd,TYPE2,InstanceUnitType,TListSrc>{
00819       };
00821       template<class TList,class TYPE2 ,template <class,class> class InstanceUnitType>
00822       class Field2
00823       :
00824       public Field2Helper<TList,TYPE2,InstanceUnitType,TList>{
00825       public:
00826          public:
00827          template <typename T>
00828          struct RebingByType{
00829                typedef InstanceUnitType<T,TYPE2> type;
00830            };
00831          template <size_t Index>
00832          struct RebingByIndex{
00833                typedef  InstanceUnitType<typename  TypeAtTypeList<TList,Index>::type,TYPE2 > type;
00834            };
00835       };
00837       struct FieldAccess{
00838          template<size_t Index,class IG>
00839          static inline typename IG::template RebingByIndex<Index>::type &
00840          byIndex
00841          (
00842             IG & instanceGenerator
00843          ) {
00844             return instanceGenerator;
00845          }
00846 
00847          template<size_t Index,class IG>
00848          static inline const typename IG::template RebingByIndex<Index>::type &
00849          byIndex
00850          (
00851             const IG & instanceGenerator
00852          ) {
00853             return instanceGenerator;
00854          }
00855 
00856          template<class T,class IG>
00857          static inline typename IG::template RebingByType<T>::type &
00858          byType
00859          (
00860             IG & instanceGenerator
00861          ) {
00862             return instanceGenerator;
00863          }
00864 
00865          template<class T,class IG>
00866          static inline const typename IG::template RebingByType<T>::type &
00867          byType
00868          (
00869             const IG & instanceGenerator
00870          ) {
00871             return instanceGenerator;
00872          }
00873       };
00875       template<class Factor,size_t FunctionIndex>
00876       class GetFunctionFromFactor
00877       {
00878          typedef typename  Factor::FunctionTypeList FunctionTypeList;
00879       public:
00880          typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
00881          static inline const  FunctionType & get(const Factor & factor) {
00882             return factor. template function<FunctionIndex>();
00883          }
00884          static inline  FunctionType & get( Factor & factor) {
00885             return factor. template function<FunctionIndex>();
00886          }
00887       };
00889       template<class Factor,size_t FunctionIndex>
00890       class GetFunction;
00892       template<class T,size_t FunctionIndex>
00893       class GetFunction<opengm::Factor<T>,FunctionIndex >{
00894          typedef  typename Factor<T>::FunctionTypeList FunctionTypeList;
00895       public:
00896          typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
00897 
00898          static inline const FunctionType & get(const Factor<T> & factor) {
00899             return factor. template function<FunctionIndex>();
00900          };
00901          static inline FunctionType & get(Factor<T> & factor) {
00902             return factor. template function<FunctionIndex>();
00903          };
00904       };
00906       template<class T,class I,class L,size_t FunctionIndex>
00907       class GetFunction<IndependentFactor<T,I,L>,FunctionIndex >{
00908       public:
00909          typedef typename IndependentFactor<T,I,L>::FunctionType FunctionType;
00910          static inline const FunctionType & get(const IndependentFactor<T,I,L> & factor) {
00911             return factor.template  function<0>();
00912          };
00913          static inline FunctionType & get(IndependentFactor<T,I,L> & factor) {
00914             return factor.template  function<0>();
00915          };
00916       };
00918       template<class Factor>
00919       class GetFunctionTypeIndex;
00921       template<class T>
00922       class GetFunctionTypeIndex<opengm::Factor<T> >{
00923       public:
00924          static inline size_t get(const opengm::Factor<T> & factor) {
00925             return factor.functionType();
00926          }
00927          static inline size_t get(opengm::Factor<T> & factor) {
00928             return factor.functionType();
00929          }
00930       };
00932       template<class T,class I,class L>
00933       class GetFunctionTypeIndex<opengm::IndependentFactor<T,I,L> >{
00934       public:
00935          static inline size_t get(const opengm::IndependentFactor<T,I,L> & factor) {
00936             return 0;
00937          }
00938          static inline size_t get( opengm::IndependentFactor<T,I,L> & factor) {
00939             return 0;
00940          }
00941       };
00943       template <class T>
00944       class IsField  : opengm::meta::FalseCase{};
00946       template<class TList ,template <class> class InstanceUnitType>
00947       class IsField< meta::Field<TList,InstanceUnitType> >  : opengm::meta::TrueCase{};
00949       struct ErrorMessage{
00950          struct WRONG_FUNCTION_TYPE;
00951       };
00953       template <class MSG>
00954       struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_;
00955       template < >
00956       struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_<meta::EmptyType >{
00957       };
00959       template<bool>
00960       class Assert;
00961       template<>
00962       class Assert<true>{
00963       };
00965       template<class TLIST,size_t INITIAL_VALUE, template <size_t, size_t> class ACCUMULATOR>
00966       class Accumulate;
00968       template<class TLIST_HEAD,class TLIST_TAIL,size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
00969       class Accumulate<meta::TypeList<TLIST_HEAD,TLIST_TAIL>,INITIAL_VALUE ,ACCUMULATOR >{
00970          enum Value{
00971             value=Accumulate<
00972                TLIST_TAIL,
00973                ACCUMULATOR <
00974                   INITIAL_VALUE,
00975                   TLIST_HEAD::value
00976                >::value ,
00977                ACCUMULATOR
00978             >::value
00979          };
00980          typedef SizeT<
00981             Accumulate<
00982                TLIST_TAIL ,
00983                ACCUMULATOR<
00984                   INITIAL_VALUE,
00985                   TLIST_HEAD::value
00986                >::value ,
00987                ACCUMULATOR
00988             >::value
00989          > type;
00990       };
00992       template<size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
00993       class Accumulate<meta::ListEnd,INITIAL_VALUE ,ACCUMULATOR >{
00994          enum Value{
00995             value=INITIAL_VALUE
00996          };
00997          typedef SizeT<INITIAL_VALUE> type;
00998       };
00999       
01000       template<class T>
01001       struct PromoteToFloatingPoint{
01002          typedef typename meta::If< 
01003             meta::IsFloatingPoint<T>::value ,
01004             T,
01005             float
01006          >::type type;
01007       };
01008       
01009    } // namespace meta
01010    
01011    
01021    template
01022    <
01023    class T1,
01024    class T2 = meta::ListEnd,
01025    class T3 = meta::ListEnd,
01026    class T4 = meta::ListEnd,
01027    class T5 = meta::ListEnd,
01028    class T6 = meta::ListEnd,
01029    class T7 = meta::ListEnd,
01030    class T8 = meta::ListEnd,
01031    class T9 = meta::ListEnd,
01032    class T10 = meta::ListEnd,
01033    class T11 = meta::ListEnd,
01034    class T12 = meta::ListEnd,
01035    class T13 = meta::ListEnd,
01036    class T14 = meta::ListEnd,
01037    class T15 = meta::ListEnd
01038    >
01039    struct FunctionTypeListGenerator {
01040       typedef meta::TypeList<T1, typename FunctionTypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
01041    };
01042 
01043    template< >
01044    struct FunctionTypeListGenerator<meta::ListEnd> {
01045       typedef meta::ListEnd type;
01046    };
01047 
01049 
01050 } // namespace opengm
01051 
01052 #endif // #ifndef OPENGM_METAPROGRAMMING
01053 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3