graphicalmodel_function_wrapper.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
00003 #define OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
00004 
00005 #include <vector>
00006 #include <set>
00007 #include <algorithm>
00008 #include <functional>
00009 #include <numeric>
00010 #include <map>
00011 #include <list>
00012 #include <set>
00013 #include <functional>
00014 
00015 #include "opengm/functions/explicit_function.hxx"
00016 #include "opengm/functions/function_properties.hxx"
00017 #include "opengm/opengm.hxx"
00018 #include "opengm/utilities/indexing.hxx"
00019 #include "opengm/utilities/sorting.hxx"
00020 #include "opengm/utilities/functors.hxx"
00021 #include "opengm/utilities/metaprogramming.hxx"
00022 #include "opengm/operations/minimizer.hxx"
00023 #include "opengm/graphicalmodel/graphicalmodel_factor_operator.hxx"
00024 #include "opengm/graphicalmodel/graphicalmodel_factor_accumulator.hxx"
00025 
00026 namespace opengm {
00027 
00029 
00030 template<
00031    class T,
00032    class OPERATOR,
00033    class FUNCTION_TYPE_LIST ,
00034    class SPACE ,
00035    bool MUTABLE
00036 >
00037 class GraphicalModel;
00038 
00039 template<class GRAPHICAL_MODEL> class Factor;
00040 
00041 namespace detail_graphical_model {
00042 
00043    #define OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( RETURN_TYPE , FUNCTION_NAME ) \
00044    template<size_t NUMBER_OF_FUNCTIONS> \
00045    template<class GM> \
00046    inline RETURN_TYPE \
00047    FunctionWrapper<NUMBER_OF_FUNCTIONS>::FUNCTION_NAME \
00048    ( \
00049       GM const * gm, \
00050       const size_t functionIndex, \
00051       const size_t functionType \
00052    ) { \
00053      typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;  \
00054       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) { \
00055          return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00056       } \
00057       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) { \
00058          if(functionType==0) \
00059             return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00060          else \
00061             return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00062       } \
00063       if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) { \
00064          switch(functionType) { \
00065             case 0: \
00066                return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00067             case 1: \
00068                return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00069             case 2: \
00070                return gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00071             case 3: \
00072                return gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00073             case 4: \
00074                return gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00075             case 5: \
00076                return gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00077             case 6: \
00078                return gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00079             case 7: \
00080                return gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00081             case 8: \
00082                return gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00083             case 9: \
00084                return gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00085             case 10: \
00086                return gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00087             case 11: \
00088                return gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00089             case 12: \
00090                return gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00091             case 13: \
00092                return gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00093             case 14: \
00094                return gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00095             case 15: \
00096                return gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
00097             default: \
00098                return FunctionWrapperExecutor< \
00099                   16, \
00100                   NUMBER_OF_FUNCTIONS, \
00101                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value \
00102                >::FUNCTION_NAME(gm,functionIndex,functionType); \
00103          } \
00104       } \
00105    } \
00106    template<size_t IX, size_t DX> \
00107    template<class GM> \
00108    RETURN_TYPE FunctionWrapperExecutor<IX, DX, false>::FUNCTION_NAME \
00109    ( \
00110       GM const* gm, \
00111       const size_t functionIndex, \
00112       const size_t functionType \
00113    ) { \
00114       if(functionType==IX) { \
00115          return gm->template functions<IX>()[functionIndex].FUNCTION_NAME(); \
00116       } \
00117       else { \
00118          return FunctionWrapperExecutor<IX+1, DX, meta::Bool<IX+1==DX>::value >::FUNCTION_NAME (gm, functionIndex,functionType); \
00119       } \
00120    } \
00121    template<size_t IX, size_t DX> \
00122    template<class GM> \
00123    RETURN_TYPE FunctionWrapperExecutor<IX, DX, true>::FUNCTION_NAME \
00124    ( \
00125       GM const* gm, \
00126       const size_t functionIndex, \
00127       const size_t functionType \
00128    ) { \
00129       throw RuntimeError("Incorrect function type id."); \
00130    }
00131     
00132    template<size_t IX, size_t DX, bool end>
00133    struct FunctionWrapperExecutor;
00134 
00135    template<size_t IX, size_t DX>
00136    struct FunctionWrapperExecutor<IX,DX,false>{
00137       template <class GM,class ITERATOR>
00138       static void  getValues(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00139       template <class GM,class ITERATOR>
00140       static void  getValuesSwitchedOrder(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00141       template <class GM,class ITERATOR>
00142       static typename GM::ValueType  getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00143       template <class GM,class FUNCTOR>
00144       static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00145       template <class GM,class FUNCTOR>
00146       static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00147       template <class GM,class FUNCTOR>
00148       static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00149       template <class GM,class FUNCTOR>
00150       static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00151       template <class GM,int PROPERTY>
00152       static bool  binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
00153       template <class GM,int PROPERTY>
00154       static typename GM::ValueType  valueProperty(const GM *,const typename GM::IndexType ,const size_t );
00155       template <class GM>
00156       static void addFactorFunctionAdjacency(GM * ,const size_t ,const size_t , const size_t );
00157       template <class GM>
00158       static void swapAndDeleteFunction(GM * , const size_t , const size_t , const size_t , size_t& );
00159       template <class GM>
00160       static size_t numberOfFunctions(const GM *,const size_t );
00161       template <class GM>
00162       static void initializeFactorFunctionAdjacencies(GM *);
00163       template <class GM_SOURCE,class GM_DEST>
00164       static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
00165       template<class GM>
00166       static bool isPotts(GM const *,const size_t ,const size_t);
00167       template<class GM>
00168       static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
00169       template<class GM>
00170       static bool isSubmodular(GM const *,const size_t ,const size_t);
00171       template<class GM>
00172       static typename GM::ValueType min(GM const *,const size_t ,const size_t);
00173       template<class GM>
00174       static typename GM::ValueType max(GM const *,const size_t ,const size_t);
00175       template<class GM>
00176       static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
00177       template<class GM>
00178       static typename GM::ValueType product(GM const *,const size_t ,const size_t);
00179       template<class GM>
00180       static bool isSquaredDifference(GM const *,const size_t ,const size_t);
00181       template<class GM>
00182       static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
00183       template<class GM>
00184       static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
00185       template<class GM>
00186       static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
00187    };
00188 
00189    template<size_t IX, size_t DX>
00190    struct FunctionWrapperExecutor<IX,DX,true>{
00191       template <class GM,class ITERATOR>
00192       static typename GM::ValueType  getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00193       template <class GM,class ITERATOR>
00194       static void getValues(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00195       template <class GM,class ITERATOR>
00196       static void getValuesSwitchedOrder(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00197       template <class GM,class FUNCTOR>
00198       static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00199       template <class GM,class FUNCTOR>
00200       static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00201       template <class GM,class FUNCTOR>
00202       static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00203       template <class GM,class FUNCTOR>
00204       static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00205       template <class GM,int PROPERTY>
00206       static bool  binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
00207       template <class GM,int PROPERTY>
00208       static typename GM::ValueType  valueProperty(const GM *,const typename GM::IndexType ,const size_t );
00209       template <class GM>
00210       static void addFactorFunctionAdjacency(GM * ,const size_t ,const size_t , const size_t );
00211       template <class GM>
00212       static void swapAndDeleteFunction(GM * , const size_t , const size_t , const size_t , size_t& );
00213       template <class GM>
00214       static size_t numberOfFunctions(const GM *,const size_t functionTypeIndex);
00215       template <class GM>
00216       static void initializeFactorFunctionAdjacencies(GM *);
00217       template <class GM_SOURCE,class GM_DEST>
00218       static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
00219       template<class GM>
00220       static bool isPotts(GM const *,const size_t ,const size_t);
00221       template<class GM>
00222       static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
00223       template<class GM>
00224       static bool isSubmodular(GM const *,const size_t,const size_t );
00225       template<class GM>
00226       static typename GM::ValueType min(GM const *,const size_t ,const size_t);
00227       template<class GM>
00228       static typename GM::ValueType max(GM const *,const size_t ,const size_t);
00229       template<class GM>
00230       static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
00231       template<class GM>
00232       static typename GM::ValueType product(GM const *,const size_t ,const size_t);
00233       template<class GM>
00234       static bool isSquaredDifference(GM const *,const size_t ,const size_t);
00235       template<class GM>
00236       static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
00237       template<class GM>
00238       static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
00239       template<class GM>
00240       static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
00241    };
00242 
00243    template<size_t NUMBER_OF_FUNCTIONS>
00244    struct FunctionWrapper{
00245        
00246       template <class GM,class OUT_ITERATOR>
00247       static void  getValues(const GM *,OUT_ITERATOR,const typename GM::IndexType ,const size_t );
00248       template <class GM,class OUT_ITERATOR>
00249       static void  getValuesSwitchedOrder(const GM *,OUT_ITERATOR,const typename GM::IndexType ,const size_t );
00250       template <class GM,class ITERATOR>
00251       static typename GM::ValueType  getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
00252       template <class GM,class FUNCTOR>
00253       static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00254       template <class GM,class FUNCTOR>
00255       static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
00256       template <class GM,class FUNCTOR>
00257       static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t ); 
00258       template <class GM,class FUNCTOR>
00259       static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t ); 
00260       template <class GM,int PROPERTY>
00261       static bool  binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
00262       template <class GM,int PROPERTY>
00263       static typename GM::ValueType  valueProperty(const GM *,const typename GM::IndexType ,const size_t );
00264       template <class GM>
00265       static void addFactorFunctionAdjacency(GM * ,const size_t ,const size_t , const size_t );
00266       template <class GM>
00267       static void swapAndDeleteFunction(GM * , const size_t , const size_t , const size_t , size_t& );
00268       template <class GM>
00269       static size_t numberOfFunctions(const GM *,const size_t functionTypeIndex);
00270       template <class GM>
00271       static void initializeFactorFunctionAdjacencies(GM *);
00272       template <class GM_SOURCE,class GM_DEST>
00273       static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
00274       template<class GM>
00275       static bool isPotts(GM const *,const size_t,const size_t);
00276       template<class GM>
00277       static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
00278       template<class GM>
00279       static bool isSubmodular(GM const *,const size_t ,const size_t);
00280       template<class GM>
00281       static typename GM::ValueType min(GM const *,const size_t ,const size_t);
00282       template<class GM>
00283       static typename GM::ValueType max(GM const *,const size_t ,const size_t);
00284       template<class GM>
00285       static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
00286       template<class GM>
00287       static typename GM::ValueType product(GM const *,const size_t ,const size_t);
00288       template<class GM>
00289       static bool isSquaredDifference(GM const *,const size_t ,const size_t);
00290       template<class GM>
00291       static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
00292       template<class GM>
00293       static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
00294       template<class GM>
00295       static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
00296    };
00297 } //namespace detail_graphical_model
00298 
00299 // implementaion
00300 namespace detail_graphical_model {
00301    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isSubmodular)
00302    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isPotts)
00303    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isGeneralizedPotts)
00304    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isSquaredDifference)
00305    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isTruncatedSquaredDifference)
00306    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isAbsoluteDifference)
00307    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isTruncatedAbsoluteDifference)
00308    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, min)
00309    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, max)
00310    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, sum)
00311    OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, product)
00312 
00313    template<size_t IX, size_t DX>
00314    template<class GM>
00315    void FunctionWrapperExecutor<IX, DX, false>::addFactorFunctionAdjacency
00316    (
00317       GM * gm,
00318       const size_t functionIndex,
00319       const size_t factorIndex,
00320       const size_t rtIndex
00321    ) {
00322       if(IX==rtIndex) {
00323          OPENGM_ASSERT(functionIndex< gm->template functions<IX>().size());
00324          OPENGM_ASSERT(functionIndex< gm->template factorFunctionAdjacencies<IX>().size());
00325          gm->template factorFunctionAdjacencies<IX>()[functionIndex].insert(factorIndex);
00326       }
00327       else {
00328          FunctionWrapperExecutor<IX+1, DX, meta::Bool<IX+1==DX>::value >::addFactorFunctionAdjacency(gm, functionIndex, factorIndex, rtIndex);
00329       }
00330    }
00331 
00332    template<size_t IX, size_t DX>
00333    template<class GM>
00334    void FunctionWrapperExecutor<IX, DX, true>::addFactorFunctionAdjacency
00335    (
00336       GM * gm,
00337       const size_t functionIndex,
00338       const size_t factorIndex,
00339       const size_t rtIndex
00340    ) {
00341       throw RuntimeError("Incorrect function type id.");
00342    }
00343 
00344    template<size_t IX, size_t DX>
00345    template<class GM>
00346    inline void FunctionWrapperExecutor<IX, DX, false>::swapAndDeleteFunction
00347    (
00348       GM * gm,
00349       const size_t currenFactorIndex,
00350       const size_t currentFunctionIndex,
00351       const size_t currentFunctionType,
00352       size_t& explicitFunctionIndex
00353    ) {
00354       typedef meta::SizeT<
00355          meta::Decrement<
00356             GM::NrOfFunctionTypes
00357          >::value
00358       > ExplicitFunctionPosition;
00359       if(IX==currentFunctionType) {
00360          bool swappedFunctionIsNewOne=false;
00361          if(gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex].size() == 1) {
00362             if(currentFunctionIndex== gm->template functions<IX>().size()-1) {
00363                 gm->template functions<IX>().pop_back();
00364                 gm->template factorFunctionAdjacencies<IX>().pop_back();
00365             }
00366             else{
00367                if(   IX==ExplicitFunctionPosition::value &&
00368                      explicitFunctionIndex == gm->template functions<ExplicitFunctionPosition::value>().size() - 1) {
00369                   swappedFunctionIsNewOne=true;
00370                }
00371                //meta::FieldAccess::template byIndex<0>(this->functionDataField_).functionData_.functions_.size();
00372                gm->template functions<IX>()[currentFunctionIndex] =gm->template functions<IX>().back();
00373                gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex] =gm->template factorFunctionAdjacencies<IX>().back();
00374                gm->template functions<IX>().pop_back();
00375                gm->template factorFunctionAdjacencies<IX>().pop_back();
00376                typename RandomAccessSet<typename  GM::IndexType>::const_iterator begin =gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex].begin();
00377                typename RandomAccessSet<typename  GM::IndexType>::const_iterator end =gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex].end();
00378                while(begin != end) {
00379                   OPENGM_ASSERT(*begin<gm->factors_.size());
00380                   gm->factors_[*begin].functionIndex_ = currentFunctionIndex;
00381                   ++begin;
00382                }
00383             }
00384 
00385             if(swappedFunctionIsNewOne) {
00386                explicitFunctionIndex = currentFunctionIndex;
00387             }
00388          }
00389          else {
00390             // remove factor index from adjaceny
00391             //const RandomAccessSet<typename  GM::IndexType>& adset = gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex];
00392             //typename RandomAccessSet<typename  GM::IndexType>::const_iterator begin = adset.begin();
00393             //typename RandomAccessSet<typename  GM::IndexType>::const_iterator end = adset.end();
00394             gm->template factorFunctionAdjacencies<IX>()[currentFunctionIndex].erase(currenFactorIndex);
00395          }
00396       }
00397       else {
00398          typedef FunctionWrapperExecutor<IX+1, DX, meta::Bool<IX+1==DX>::value> NewExecutorType;
00399          NewExecutorType::swapAndDeleteFunction(gm, currenFactorIndex, currentFunctionIndex, currentFunctionType, explicitFunctionIndex);
00400       }
00401    }
00402 
00403    template<size_t IX, size_t DX>
00404    template<class GM>
00405    inline void FunctionWrapperExecutor<IX, DX, true>::swapAndDeleteFunction
00406    (
00407       GM * gm,
00408       const size_t currentFactorIndex,
00409       const size_t currentFunctionIndex,
00410       const size_t currentFunctionType,
00411       size_t& explicitFunctionIndex
00412    ) {
00413       throw RuntimeError("Incorrect function type id.");
00414    }
00415 
00416    template<size_t IX,size_t DX>
00417    template<class GM>
00418    inline void
00419    FunctionWrapperExecutor<IX,DX,false>::initializeFactorFunctionAdjacencies
00420    (
00421       GM * gm
00422    ) {
00423       const size_t nrOfFunctions=gm-> template functions<IX>().size();
00424       gm->template factorFunctionAdjacencies <IX>().resize(nrOfFunctions);
00425       typedef FunctionWrapperExecutor<
00426          meta::Increment<IX>::value,
00427          DX,
00428          meta::EqualNumber<meta::Increment<IX>::value,DX>::value
00429       > ExecutorType;
00430       ExecutorType::initializeFactorFunctionAdjacencies(gm);
00431    }
00432 
00433    template<size_t IX,size_t DX>
00434    template<class GM>
00435    inline void
00436    FunctionWrapperExecutor<IX,DX,true>::initializeFactorFunctionAdjacencies
00437    (
00438       GM * gm
00439    ) {
00440       for(size_t i=0;i<gm->numberOfFactors();++i) {
00441          gm->addFactorToAdjacency(gm->factors_[i].functionIndex(),i,gm->factors_[i].functionType());
00442       }
00443    }
00444 
00445    template<size_t IX,size_t DX>
00446    template<class GM,class ITERATOR>
00447    inline typename GM::ValueType
00448    FunctionWrapperExecutor<IX,DX,false>::getValue
00449    (
00450       const GM * gm,
00451       ITERATOR iterator,
00452       const typename GM::IndexType functionIndex,
00453       const size_t functionType
00454    ) {
00455       if(IX==functionType) {
00456          return gm-> template functions<IX>()[functionIndex](iterator);
00457       }
00458       else{
00459          return FunctionWrapperExecutor<
00460             meta::Increment<IX>::value,
00461             DX,
00462             meta::EqualNumber<
00463                meta::Increment<IX>::value,
00464                DX
00465             >::value
00466          >::getValue(gm,iterator,functionIndex,functionType);
00467       }
00468    }
00469    
00470    template<size_t IX,size_t DX>
00471    template <class GM,class FUNCTOR>
00472    inline void 
00473    FunctionWrapperExecutor<IX,DX,false>::forAllValuesInAnyOrder
00474    (
00475       const GM * gm,
00476       FUNCTOR & functor,
00477       const typename GM::IndexType functionIndex,
00478       const size_t functionType
00479    ) {
00480       if(IX==functionType) {
00481          gm-> template functions<IX>()[functionIndex].forAllValuesInAnyOrder(functor);
00482       }
00483       else{
00484          FunctionWrapperExecutor<
00485             meta::Increment<IX>::value,
00486             DX,
00487             meta::EqualNumber<
00488                meta::Increment<IX>::value,
00489                DX
00490             >::value
00491          >::forAllValuesInAnyOrder(gm,functor,functionIndex,functionType);
00492       }
00493    }
00494    
00495    template<size_t IX,size_t DX>
00496    template <class GM,class FUNCTOR>
00497    inline void 
00498    FunctionWrapperExecutor<IX,DX,false>::forAtLeastAllUniqueValues
00499    (
00500       const GM * gm,
00501       FUNCTOR & functor,
00502       const typename GM::IndexType functionIndex,
00503       const size_t functionType
00504    ) {
00505       if(IX==functionType) {
00506          gm-> template functions<IX>()[functionIndex].forAtLeastAllUniqueValues(functor);
00507       }
00508       else{
00509          FunctionWrapperExecutor<
00510             meta::Increment<IX>::value,
00511             DX,
00512             meta::EqualNumber<
00513                meta::Increment<IX>::value,
00514                DX
00515             >::value
00516          >::forAtLeastAllUniqueValues(gm,functor,functionIndex,functionType);
00517       }
00518    }
00519    
00520    template<size_t IX,size_t DX>
00521    template <class GM,class FUNCTOR>
00522    inline void 
00523    FunctionWrapperExecutor<IX,DX,false>::forAllValuesInOrder
00524    (
00525       const GM * gm,
00526       FUNCTOR & functor,
00527       const typename GM::IndexType functionIndex,
00528       const size_t functionType
00529    ) {
00530       if(IX==functionType) {
00531          gm-> template functions<IX>()[functionIndex].forAllValuesInOrder(functor);
00532       }
00533       else{
00534          FunctionWrapperExecutor<
00535             meta::Increment<IX>::value,
00536             DX,
00537             meta::EqualNumber<
00538                meta::Increment<IX>::value,
00539                DX
00540             >::value
00541          >::forAllValuesInOrder(gm,functor,functionIndex,functionType);
00542       }
00543    }
00544    
00545    template<size_t IX,size_t DX>
00546    template <class GM,class FUNCTOR>
00547    inline void 
00548    FunctionWrapperExecutor<IX,DX,false>::forAllValuesInSwitchedOrder
00549    (
00550       const GM * gm,
00551       FUNCTOR & functor,
00552       const typename GM::IndexType functionIndex,
00553       const size_t functionType
00554    ) {
00555       if(IX==functionType) {
00556          gm-> template functions<IX>()[functionIndex].forAllValuesInSwitchedOrder(functor);
00557       }
00558       else{
00559          FunctionWrapperExecutor<
00560             meta::Increment<IX>::value,
00561             DX,
00562             meta::EqualNumber<
00563                meta::Increment<IX>::value,
00564                DX
00565             >::value
00566          >::forAllValuesInSwitchedOrder(gm,functor,functionIndex,functionType);
00567       }
00568    }
00569    
00570    
00571    template<size_t IX,size_t DX>
00572    template <class GM,int PROPERTY>
00573    inline bool
00574    FunctionWrapperExecutor<IX,DX,false>::binaryProperty
00575    (
00576       const GM * gm,
00577       const typename GM::IndexType functionIndex,
00578       const size_t functionType
00579    ) {
00580       if(IX==functionType) {
00581          typedef typename GM::FunctionTypeList FTypeList;
00582          typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00583          return BinaryFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<IX>()[functionIndex]);
00584       }
00585       else{
00586          return FunctionWrapperExecutor<
00587             meta::Increment<IX>::value,
00588             DX,
00589             meta::EqualNumber<
00590                meta::Increment<IX>::value,
00591                DX
00592             >::value
00593          >:: template binaryProperty<GM,PROPERTY>(gm,functionIndex,functionType);
00594       }
00595    }
00596    
00597    template<size_t IX,size_t DX>
00598    template <class GM,int PROPERTY>
00599    inline typename GM::ValueType
00600    FunctionWrapperExecutor<IX,DX,false>::valueProperty
00601    (
00602       const GM * gm,
00603       const typename GM::IndexType functionIndex,
00604       const size_t functionType
00605    ) {
00606       if(IX==functionType) {
00607          typedef typename GM::FunctionTypeList FTypeList;
00608          typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00609          return ValueFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<IX>()[functionIndex]);
00610       }
00611       else{
00612          return FunctionWrapperExecutor<
00613             meta::Increment<IX>::value,
00614             DX,
00615             meta::EqualNumber<
00616                meta::Increment<IX>::value,
00617                DX
00618             >::value
00619          >:: template valueProperty<GM,PROPERTY>(gm,functionIndex,functionType);
00620       }
00621    }
00622     
00623    template<size_t IX,size_t DX>
00624    template<class GM,class ITERATOR>
00625    inline void
00626    FunctionWrapperExecutor<IX,DX,false>::getValues
00627    (
00628       const GM * gm,
00629       ITERATOR iterator,
00630       const typename GM::IndexType functionIndex,
00631       const size_t functionType
00632    ) {
00633       if(IX==functionType) {
00634          // COPY FUNCTION TO ITERATR
00635          typedef typename GM::FunctionTypeList FTypeList;
00636          typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00637          typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
00638          
00639          const FunctionType & function = gm-> template functions<IX>()[functionIndex];
00640          ShapeWalker< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
00641          for (size_t i = 0; i < function.size(); ++i) {
00642                *iterator = function(walker.coordinateTuple().begin());
00643                ++iterator;
00644                ++walker;
00645          }
00646 
00647       }
00648       else{
00649          return FunctionWrapperExecutor<
00650             meta::Increment<IX>::value,
00651             DX,
00652             meta::EqualNumber<
00653                meta::Increment<IX>::value,
00654                DX
00655             >::value
00656          >::getValues(gm,iterator,functionIndex,functionType);
00657       }
00658    }
00659    
00660    template<size_t IX,size_t DX>
00661    template<class GM,class ITERATOR>
00662    inline void
00663    FunctionWrapperExecutor<IX,DX,false>::getValuesSwitchedOrder
00664    (
00665       const GM * gm,
00666       ITERATOR iterator,
00667       const typename GM::IndexType functionIndex,
00668       const size_t functionType
00669    ) {
00670       if(IX==functionType) {
00671          // COPY FUNCTION TO ITERATR
00672          typedef typename GM::FunctionTypeList FTypeList;
00673          typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00674          typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
00675          
00676          const FunctionType & function = gm-> template functions<IX>()[functionIndex];
00677          ShapeWalkerSwitchedOrder< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
00678          for (size_t i = 0; i < function.size(); ++i) {
00679                *iterator = function(walker.coordinateTuple().begin());
00680                ++iterator;
00681                ++walker;
00682          }
00683 
00684       }
00685       else{
00686          return FunctionWrapperExecutor<
00687             meta::Increment<IX>::value,
00688             DX,
00689             meta::EqualNumber<
00690                meta::Increment<IX>::value,
00691                DX
00692             >::value
00693          >::getValuesSwitchedOrder(gm,iterator,functionIndex,functionType);
00694       }
00695    }
00696     
00697    template<size_t IX,size_t DX>
00698    template<class GM,class ITERATOR>
00699    inline void
00700    FunctionWrapperExecutor<IX,DX,true>::getValues
00701    (
00702       const GM * gm,
00703       ITERATOR iterator,
00704       const typename GM::IndexType functionIndex,
00705       const size_t functionType
00706    ) {
00707       throw RuntimeError("Incorrect function type id.");
00708    }
00709    template<size_t IX,size_t DX>
00710    template<class GM,class ITERATOR>
00711    inline void
00712    FunctionWrapperExecutor<IX,DX,true>::getValuesSwitchedOrder
00713    (
00714       const GM * gm,
00715       ITERATOR iterator,
00716       const typename GM::IndexType functionIndex,
00717       const size_t functionType
00718    ) {
00719       throw RuntimeError("Incorrect function type id.");
00720    }
00721    
00722    template<size_t IX,size_t DX>
00723    template<class GM,class ITERATOR>
00724    inline typename GM::ValueType
00725    FunctionWrapperExecutor<IX,DX,true>::getValue
00726    (
00727       const GM * gm,
00728       ITERATOR iterator,
00729       const typename GM::IndexType functionIndex,
00730       const size_t functionType
00731    ) {
00732       throw RuntimeError("Incorrect function type id.");
00733       return typename GM::ValueType();
00734    }
00735    
00736     template<size_t IX,size_t DX>
00737    template <class GM,class FUNCTOR>
00738    inline void 
00739    FunctionWrapperExecutor<IX,DX,true>::forAllValuesInAnyOrder
00740    (
00741       const GM * gm,
00742       FUNCTOR & functor,
00743       const typename GM::IndexType functionIndex,
00744       const size_t functionType
00745    ) {
00746       throw RuntimeError("Incorrect function type id.");
00747    }
00748 
00749    template<size_t IX,size_t DX>
00750    template <class GM,class FUNCTOR>
00751    inline void  
00752    FunctionWrapperExecutor<IX,DX,true>::forAtLeastAllUniqueValues
00753    (
00754       const GM * gm,
00755       FUNCTOR & functor,
00756       const typename GM::IndexType functionIndex,
00757       const size_t functionType
00758    ) {
00759       throw RuntimeError("Incorrect function type id.");
00760    }
00761    
00762    template<size_t IX,size_t DX>
00763    template <class GM,class FUNCTOR>
00764    inline void 
00765    FunctionWrapperExecutor<IX,DX,true>::forAllValuesInOrder
00766    (
00767       const GM * gm,
00768       FUNCTOR & functor,
00769       const typename GM::IndexType functionIndex,
00770       const size_t functionType
00771    ) {
00772       throw RuntimeError("Incorrect function type id.");
00773    }
00774    
00775    template<size_t IX,size_t DX>
00776    template <class GM,class FUNCTOR>
00777    inline void 
00778    FunctionWrapperExecutor<IX,DX,true>::forAllValuesInSwitchedOrder
00779    (
00780       const GM * gm,
00781       FUNCTOR & functor,
00782       const typename GM::IndexType functionIndex,
00783       const size_t functionType
00784    ) {
00785       throw RuntimeError("Incorrect function type id.");
00786    }
00787    
00788    template<size_t IX,size_t DX>
00789    template <class GM,int PROPERTY>
00790    inline bool
00791    FunctionWrapperExecutor<IX,DX,true>::binaryProperty
00792    (
00793       const GM * gm,
00794       const typename GM::IndexType functionIndex,
00795       const size_t functionType
00796    ) {
00797       throw RuntimeError("Incorrect function type id.");
00798       return false;
00799    }
00800    
00801    template<size_t IX,size_t DX>
00802    template <class GM,int PROPERTY>
00803    inline typename GM::ValueType
00804    FunctionWrapperExecutor<IX,DX,true>::valueProperty
00805    (
00806       const GM * gm,
00807       const typename GM::IndexType functionIndex,
00808       const size_t functionType
00809    ) {
00810       throw RuntimeError("Incorrect function type id.");
00811       return false;
00812    }
00813    
00814    template<size_t IX,size_t DX>
00815    template<class GM>
00816    inline size_t
00817    FunctionWrapperExecutor<IX,DX,false>::numberOfFunctions
00818    (
00819       const GM * gm,
00820       const size_t functionType
00821    ) {
00822       if(IX==functionType) {
00823          return gm->template functions<IX>().size();
00824       }
00825       else{
00826          return FunctionWrapperExecutor<
00827             meta::Increment<IX>::value,
00828             DX,
00829             meta::EqualNumber<
00830                meta::Increment<IX>::value,
00831                DX
00832             >::value
00833          >::numberOfFunctions(gm,functionType);
00834       }
00835    }
00836 
00837    template<size_t IX,size_t DX>
00838    template<class GM>
00839    inline size_t
00840    FunctionWrapperExecutor<IX,DX,true>::numberOfFunctions
00841    (
00842       const GM * gm,
00843       const size_t functionType
00844    ) {
00845       throw RuntimeError("Incorrect function type id.");
00846    }
00847 
00848    template<size_t IX,size_t DX>
00849    template<class GM_SOURCE,class GM_DEST>
00850    inline void
00851    FunctionWrapperExecutor<IX,DX,false>::assignFunctions
00852    (
00853       const GM_SOURCE & gmSource,
00854       GM_DEST & gmDest
00855    ) {
00856       typedef typename meta::TypeAtTypeList<
00857          typename GM_SOURCE::FunctionTypeList ,
00858          IX
00859       >::type SourceTypeAtIX;
00860       typedef meta::SizeT<
00861          meta::GetIndexInTypeList<
00862             typename GM_DEST::FunctionTypeList,
00863             SourceTypeAtIX
00864          >::value
00865       > PositionOfSourceTypeInDestType;
00866       gmDest.template functions<PositionOfSourceTypeInDestType::value> () =
00867          gmSource.template functions<IX> ();
00868 
00869       //recursive call to the rest
00870       FunctionWrapperExecutor<
00871          meta::Increment<IX>::value,
00872          DX,
00873          meta::EqualNumber<
00874             meta::Increment<IX>::value,
00875             DX
00876          >::value
00877       >::assignFunctions(gmSource,gmDest);
00878    }
00879 
00880    template<size_t IX,size_t DX>
00881    template<class GM_SOURCE,class GM_DEST>
00882    inline void
00883    FunctionWrapperExecutor<IX,DX,true>::assignFunctions
00884    (
00885       const GM_SOURCE & gmSource,
00886       GM_DEST & gmDest
00887    ) {
00888    }
00889 
00890    template<size_t NUMBER_OF_FUNCTIONS>
00891    template<class GM_SOURCE,class GM_DEST>
00892    inline void
00893    FunctionWrapper<NUMBER_OF_FUNCTIONS>::assignFunctions
00894    (
00895       const GM_SOURCE & gmSource,
00896       GM_DEST & gmDest
00897    ) {
00898       typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
00899       return ExecutorType::assignFunctions(gmSource, gmDest);
00900    }
00901 
00902    template<size_t NUMBER_OF_FUNCTIONS>
00903    template<class GM>
00904    inline size_t
00905    FunctionWrapper<NUMBER_OF_FUNCTIONS>::numberOfFunctions
00906    (
00907       const GM * gm,
00908       const size_t functionType
00909    ) {
00910       typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
00911       return ExecutorType::numberOfFunctions(gm, functionType);
00912    }
00913    
00914    
00915    template<size_t NUMBER_OF_FUNCTIONS>
00916    template<class GM,class ITERATOR>
00917    inline void
00918    FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValues
00919    (
00920       const GM *  gm,
00921       ITERATOR iterator,
00922       const typename GM::IndexType functionIndex,
00923       const size_t functionType
00924    ) {
00925         FunctionWrapperExecutor<
00926              0,
00927              NUMBER_OF_FUNCTIONS,
00928              opengm::meta::BiggerOrEqualNumber<0,NUMBER_OF_FUNCTIONS>::value
00929         >::getValues(gm,iterator,functionIndex,functionType);
00930    }
00931    
00932    template<size_t NUMBER_OF_FUNCTIONS>
00933    template<class GM,class ITERATOR>
00934    inline void
00935    FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValuesSwitchedOrder
00936    (
00937       const GM *  gm,
00938       ITERATOR iterator,
00939       const typename GM::IndexType functionIndex,
00940       const size_t functionType
00941    ) {
00942         FunctionWrapperExecutor<
00943              0,
00944              NUMBER_OF_FUNCTIONS,
00945              opengm::meta::BiggerOrEqualNumber<0,NUMBER_OF_FUNCTIONS>::value
00946         >::getValuesSwitchedOrder(gm,iterator,functionIndex,functionType);
00947    }
00948    
00949    template<size_t NUMBER_OF_FUNCTIONS>
00950    template<class GM,class ITERATOR>
00951    inline typename GM::ValueType
00952    FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValue
00953    (
00954       const GM *  gm,
00955       ITERATOR iterator,
00956       const typename GM::IndexType functionIndex,
00957       const size_t functionType
00958    ) {
00959       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
00960       // special implementation if there is only one function typelist
00961       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
00962          return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
00963       }
00964       // special implementation if there are only two functions in the typelist
00965       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
00966          if(functionType==0)
00967             return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
00968          else
00969             return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex](iterator);
00970       }
00971       // general case : 3 or more functions in the typelist
00972       if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
00973          switch(functionType) {
00974             case 0:
00975                return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
00976             case 1:
00977                return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex](iterator);
00978             case 2:
00979                return gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex](iterator);
00980             case 3:
00981                return gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex](iterator);
00982             case 4:
00983                return gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex](iterator);
00984             case 5:
00985                return gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex](iterator);
00986             case 6:
00987                return gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex](iterator);
00988             case 7:
00989                return gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex](iterator);
00990             case 8:
00991                return gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex](iterator);
00992             case 9:
00993                return gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex](iterator);
00994             case 10:
00995                return gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex](iterator);
00996             case 11:
00997                return gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex](iterator);
00998             case 12:
00999                return gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex](iterator);
01000             case 13:
01001                return gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex](iterator);
01002             case 14:
01003                return gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex](iterator);
01004             case 15:
01005                return gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex](iterator);
01006             default:
01007                // meta/template recursive "if-else" generation if the
01008                // function index is bigger than 15
01009                return FunctionWrapperExecutor<
01010                   16,
01011                   NUMBER_OF_FUNCTIONS,
01012                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01013                >::getValue(gm,iterator,functionIndex,functionType);
01014          }
01015       }
01016    }
01017    
01018    
01019    template<size_t NUMBER_OF_FUNCTIONS>
01020    template<class GM,class FUNCTOR>
01021    inline void 
01022    FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInAnyOrder
01023    (
01024       const GM *  gm,
01025       FUNCTOR &  functor,
01026       const typename GM::IndexType functionIndex,
01027       const size_t functionType
01028    ) {
01029       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01030       // special implementation if there is only one function typelist
01031       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
01032          gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01033       }
01034       // special implementation if there are only two functions in the typelist
01035       else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01036          if(functionType==0)
01037             gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01038          else
01039             gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01040       }
01041       // general case : 3 or more functions in the typelist
01042       else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01043          switch(functionType) {
01044             case 0:
01045                 gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01046                 break;
01047             case 1:
01048                 gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01049                 break;
01050             case 2:
01051                 gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01052                 break;
01053             case 3:
01054                 gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01055                 break;
01056             case 4:
01057                 gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01058                 break;
01059             case 5:
01060                 gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01061                 break;
01062             case 6:
01063                 gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01064                 break;
01065             case 7:
01066                 gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01067                 break;
01068             case 8:
01069                 gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01070                 break;
01071             case 9:
01072                 gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01073                 break;
01074             case 10:
01075                 gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01076                 break;
01077             case 11:
01078                 gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01079                 break;
01080             case 12:
01081                 gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01082                 break;
01083             case 13:
01084                 gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01085                 break;
01086             case 14:
01087                 gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01088                 break;
01089             case 15:
01090                 gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
01091                 break;
01092             default:
01093                // meta/template recursive "if-else" generation if the
01094                // function index is bigger than 15
01095                FunctionWrapperExecutor<
01096                   16,
01097                   NUMBER_OF_FUNCTIONS,
01098                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01099                >::forAllValuesInAnyOrder(gm,functor,functionIndex,functionType);
01100          }
01101       }
01102    }
01103    
01104    
01105    template<size_t NUMBER_OF_FUNCTIONS>
01106    template<class GM,class FUNCTOR>
01107    inline void 
01108    FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAtLeastAllUniqueValues
01109    (
01110       const GM *  gm,
01111       FUNCTOR &  functor,
01112       const typename GM::IndexType functionIndex,
01113       const size_t functionType
01114    ) {
01115       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01116       // special implementation if there is only one function typelist
01117       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
01118          gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01119       }
01120       // special implementation if there are only two functions in the typelist
01121       else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01122          if(functionType==0)
01123             gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01124          else
01125             gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01126       }
01127       // general case : 3 or more functions in the typelist
01128       else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01129          switch(functionType) {
01130             case 0:
01131                 gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01132                 break;
01133             case 1:
01134                 gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01135                 break;
01136             case 2:
01137                 gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01138                 break;
01139             case 3:
01140                 gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01141                 break;
01142             case 4:
01143                 gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01144                 break;
01145             case 5:
01146                 gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01147                 break;
01148             case 6:
01149                 gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01150                 break;
01151             case 7:
01152                 gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01153                 break;
01154             case 8:
01155                 gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01156                 break;
01157             case 9:
01158                 gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01159                 break;
01160             case 10:
01161                 gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01162                 break;
01163             case 11:
01164                 gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01165                 break;
01166             case 12:
01167                 gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01168                 break;
01169             case 13:
01170                 gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01171                 break;
01172             case 14:
01173                 gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01174                 break;
01175             case 15:
01176                 gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
01177                 break;
01178             default:
01179                // meta/template recursive "if-else" generation if the
01180                // function index is bigger than 15
01181                FunctionWrapperExecutor<
01182                   16,
01183                   NUMBER_OF_FUNCTIONS,
01184                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01185                >::forAtLeastAllUniqueValues(gm,functor,functionIndex,functionType);
01186          }
01187       }
01188    }
01189 
01190    template<size_t NUMBER_OF_FUNCTIONS>
01191    template<class GM,class FUNCTOR>
01192    inline void 
01193    FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInOrder
01194    (
01195       const GM *  gm,
01196       FUNCTOR &  functor,
01197       const typename GM::IndexType functionIndex,
01198       const size_t functionType
01199    ) {
01200       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01201       // special implementation if there is only one function typelist
01202       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
01203          gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01204       }
01205       // special implementation if there are only two functions in the typelist
01206       else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01207          if(functionType==0)
01208             gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01209          else
01210             gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01211       }
01212       // general case : 3 or more functions in the typelist
01213       else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01214          switch(functionType) {
01215             case 0:
01216                 gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01217                 break;
01218             case 1:
01219                 gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01220                 break;
01221             case 2:
01222                 gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01223                 break;
01224             case 3:
01225                 gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01226                 break;
01227             case 4:
01228                 gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01229                 break;
01230             case 5:
01231                 gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01232                 break;
01233             case 6:
01234                 gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01235                 break;
01236             case 7:
01237                 gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01238                 break;
01239             case 8:
01240                 gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01241                 break;
01242             case 9:
01243                 gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01244                 break;
01245             case 10:
01246                 gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01247                 break;
01248             case 11:
01249                 gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01250                 break;
01251             case 12:
01252                 gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01253                 break;
01254             case 13:
01255                 gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01256                 break;
01257             case 14:
01258                 gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01259                 break;
01260             case 15:
01261                 gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
01262                 break;
01263             default:
01264                // meta/template recursive "if-else" generation if the
01265                // function index is bigger than 15
01266                FunctionWrapperExecutor<
01267                   16,
01268                   NUMBER_OF_FUNCTIONS,
01269                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01270                >::forAllValuesInOrder(gm,functor,functionIndex,functionType);
01271          }
01272       }
01273    }
01274    
01275    
01276    template<size_t NUMBER_OF_FUNCTIONS>
01277    template<class GM,class FUNCTOR>
01278    inline void 
01279    FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInSwitchedOrder
01280    (
01281       const GM *  gm,
01282       FUNCTOR &  functor,
01283       const typename GM::IndexType functionIndex,
01284       const size_t functionType
01285    ) {
01286       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01287       // special implementation if there is only one function typelist
01288       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
01289          gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01290       }
01291       // special implementation if there are only two functions in the typelist
01292       else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01293          if(functionType==0)
01294             gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01295          else
01296             gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01297       }
01298       // general case : 3 or more functions in the typelist
01299       else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01300          switch(functionType) {
01301             case 0:
01302                 gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01303                 break;
01304             case 1:
01305                 gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01306                 break;
01307             case 2:
01308                 gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01309                 break;
01310             case 3:
01311                 gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01312                 break;
01313             case 4:
01314                 gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01315                 break;
01316             case 5:
01317                 gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01318                 break;
01319             case 6:
01320                 gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01321                 break;
01322             case 7:
01323                 gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01324                 break;
01325             case 8:
01326                 gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01327                 break;
01328             case 9:
01329                 gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01330                 break;
01331             case 10:
01332                 gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01333                 break;
01334             case 11:
01335                 gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01336                 break;
01337             case 12:
01338                 gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01339                 break;
01340             case 13:
01341                 gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01342                 break;
01343             case 14:
01344                 gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01345                 break;
01346             case 15:
01347                 gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
01348                 break;
01349             default:
01350                // meta/template recursive "if-else" generation if the
01351                // function index is bigger than 15
01352                FunctionWrapperExecutor<
01353                   16,
01354                   NUMBER_OF_FUNCTIONS,
01355                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01356                >::forAllValuesInSwitchedOrder(gm,functor,functionIndex,functionType);
01357          }
01358       }
01359    }
01360    
01361    
01362    template<size_t NUMBER_OF_FUNCTIONS>
01363    template <class GM,int PROPERTY>
01364    inline bool
01365    FunctionWrapper<NUMBER_OF_FUNCTIONS>::binaryProperty
01366    (
01367       const GM *  gm,
01368       const typename GM::IndexType functionIndex,
01369       const size_t functionType
01370    ) {
01371       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01372       typedef typename GM::FunctionTypeList FTypeList;
01373       // special implementation if there is only one function typelist
01374       
01375       
01376       #define OPENGM_FWRAPPER_PROPERTY_GEN_MACRO( NUMBER) typedef meta::Int< NUMBER > Number; \
01377          typedef meta::Int<meta::MinimumNumber<Number::value,MaxIndex::value >::value> SaveNumber; \
01378          typedef typename meta::TypeAtTypeList<FTypeList,SaveNumber::value>::type FunctionType; \
01379          return BinaryFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<SaveNumber::value>()[functionIndex])
01380       
01381       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(0);}
01382       // special implementation if there are only two functions in the typelist
01383       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01384          if(functionType==0){OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(1);}
01385          else{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(2);}
01386       }
01387       // general case : 3 or more functions in the typelist
01388       if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01389          switch(functionType) {
01390             case 0 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(0);}
01391             case 1 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(1);}
01392             case 2 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(2);}
01393             case 3 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(3);}
01394             case 4 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(4);}
01395             case 5 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(5);}
01396             case 6 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(6);}
01397             case 7 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(7);}
01398             case 8 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(8);}
01399             case 9 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(9);}
01400             case 10 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(10);}
01401             case 11 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(11);}
01402             case 12 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(12);}
01403             case 13 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(13);}
01404             case 14 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(14);}
01405             case 15 :{ OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(15);}
01406             default:{
01407                //meta/template recursive "if-else" generation if the
01408                //function index is bigger than 15
01409                return FunctionWrapperExecutor<
01410                   16,
01411                   NUMBER_OF_FUNCTIONS,
01412                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01413                >:: template binaryProperty  <GM,PROPERTY> (gm,functionIndex,functionType);
01414             }
01415          }
01416       }
01417       #undef OPENGM_FWRAPPER_PROPERTY_GEN_MACRO
01418    }
01419    
01420    template<size_t NUMBER_OF_FUNCTIONS>
01421    template <class GM,int PROPERTY>
01422    inline typename GM::ValueType
01423    FunctionWrapper<NUMBER_OF_FUNCTIONS>::valueProperty
01424    (
01425       const GM *  gm,
01426       const typename GM::IndexType functionIndex,
01427       const size_t functionType
01428    ) {
01429       typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
01430       typedef typename GM::FunctionTypeList FTypeList;
01431       // special implementation if there is only one function typelist
01432       
01433       
01434       #define OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO( NUMBER) typedef meta::Int< NUMBER > Number; \
01435          typedef meta::Int<meta::MinimumNumber<Number::value,MaxIndex::value >::value> SaveNumber; \
01436          typedef typename meta::TypeAtTypeList<FTypeList,SaveNumber::value>::type FunctionType; \
01437          return ValueFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<SaveNumber::value>()[functionIndex])
01438       
01439       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(0);}
01440       // special implementation if there are only two functions in the typelist
01441       if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
01442          if(functionType==0){OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(1);}
01443          else{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(2);}
01444       }
01445       // general case : 3 or more functions in the typelist
01446       if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
01447          switch(functionType) {
01448             case 0 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(0);}
01449             case 1 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(1);}
01450             case 2 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(2);}
01451             case 3 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(3);}
01452             case 4 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(4);}
01453             case 5 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(5);}
01454             case 6 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(6);}
01455             case 7 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(7);}
01456             case 8 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(8);}
01457             case 9 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(9);}
01458             case 10 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(10);}
01459             case 11 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(11);}
01460             case 12 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(12);}
01461             case 13 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(13);}
01462             case 14 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(14);}
01463             case 15 :{ OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(15);}
01464             default:{
01465                //meta/template recursive "if-else" generation if the
01466                //function index is bigger than 15
01467                return FunctionWrapperExecutor<
01468                   16,
01469                   NUMBER_OF_FUNCTIONS,
01470                   opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
01471                >:: template valueProperty  <GM,PROPERTY> (gm,functionIndex,functionType);
01472             }
01473          }
01474       }
01475       #undef OPENGM_FWRAPPER_PROPERTY_GEN_MACRO
01476    }
01477 
01478    template<size_t NUMBER_OF_FUNCTIONS>
01479    template<class GM>
01480    inline void
01481    FunctionWrapper<NUMBER_OF_FUNCTIONS>::initializeFactorFunctionAdjacencies
01482    (
01483       GM * gm
01484    ) {
01485       typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
01486       ExecutorType::initializeFactorFunctionAdjacencies(gm);
01487    }
01488 
01489    template<size_t NUMBER_OF_FUNCTIONS>
01490    template<class GM>
01491    inline void FunctionWrapper<NUMBER_OF_FUNCTIONS>::addFactorFunctionAdjacency
01492    (
01493       GM * gm,
01494       const size_t functionIndex,
01495       const size_t factorIndex,
01496       const size_t rtIndex
01497    ) {
01498       typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
01499       ExecutorType::addFactorFunctionAdjacency(gm, functionIndex, factorIndex, rtIndex);
01500    }
01501 
01502    template<size_t NUMBER_OF_FUNCTIONS>
01503    template<class GM>
01504    inline void FunctionWrapper<NUMBER_OF_FUNCTIONS>::swapAndDeleteFunction
01505    (
01506       GM * gm,
01507       const size_t currenFactorIndex,
01508       const size_t currentFunctionIndex,
01509       const size_t currentFunctionType,
01510       size_t& explicitFunctionIndex
01511    ) {
01512       typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
01513       ExecutorType::swapAndDeleteFunction(gm, currenFactorIndex, currentFunctionIndex, currentFunctionType, explicitFunctionIndex);
01514    }
01515 
01516 } // namespace detail_graphical_model
01517 
01519 
01520 } // namespace opengm
01521 
01522 #endif // #ifndef OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3