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 }
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 }
01051
01052 #endif // #ifndef OPENGM_METAPROGRAMMING
01053