OpenGM  2.3.x
Discrete Graphical Model Library
metaprogramming.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_METAPROGRAMMING
3 #define OPENGM_METAPROGRAMMING
4 
5 #include <limits>
6 #include <vector>
7 
9 
11 #define OPENGM_TYPELIST_1(T1) \
12 ::opengm::meta::TypeList<T1, opengm::meta::ListEnd >
13 
14 #define OPENGM_TYPELIST_2(T1, T2) \
15 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_1(T2) >
16 
17 #define OPENGM_TYPELIST_3(T1, T2, T3) \
18 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_2(T2, T3) >
19 
20 #define OPENGM_TYPELIST_4(T1, T2, T3, T4) \
21 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_3(T2, T3, T4) >
22 
23 #define OPENGM_TYPELIST_5(T1, T2, T3, T4, T5) \
24 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_4(T2, T3, T4, T5) >
25 
26 #define OPENGM_TYPELIST_6(T1, T2, T3, T4, T5, T6) \
27 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_5(T2, T3, T4, T5, T6) >
28 
29 #define OPENGM_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
30 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_6(T2, T3, T4, T5, T6, T7) >
31 
32 #define OPENGM_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
33 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
34 
35 #define OPENGM_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
36 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
37 
38 #define OPENGM_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
39 ::opengm::meta::TypeList<T1, OPENGM_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
40 
42 
43 namespace opengm {
44 
45  template<class T>
46  class Factor;
47  template<class T,class I,class L>
48  class IndependentFactor;
49  template <class LINEAR_CONSTRAINT_FUNCTION_TYPE>
50  class LinearConstraintFunctionBase;
51  template <class LINEAR_CONSTRAINT_FUNCTION_TYPE>
52  class LinearConstraintFunctionTraits;
53 
55  namespace meta {
57  template< template < typename > class TO_BIND >
58  struct Bind1{
59  template<class BIND_ARG_0>
60  struct Bind{
61  typedef TO_BIND<BIND_ARG_0> type;
62  };
63  };
65  template< template < typename ,typename > class TO_BIND >
66  struct Bind2{
67  template<class BIND_ARG_0, class BIND_ARG_1>
68  struct Bind{
69  typedef TO_BIND<BIND_ARG_0, BIND_ARG_1> type;
70  };
71  };
73  template< template < typename ,typename, typename > class TO_BIND >
74  struct Bind3{
75  template<class BIND_ARG_0, class BIND_ARG_1, class BIND_ARG_2>
76  struct Bind{
77  typedef TO_BIND<BIND_ARG_0, BIND_ARG_1, BIND_ARG_2> type;
78  };
79  };
80 
86  template<class T>
87  struct ApplyMetaFunction {
88  typedef typename T::type type;
89  };
93  template<class T>
94  struct Self {
95  typedef T type;
96  };
98  struct EmptyType {
99  };
101  struct NullType {
102  };
104  struct ListEnd {
105  };
107  struct True {
108 
109  enum Value {
110  value = 1
111  };
112  };
114  struct False {
115 
116  enum Value {
117  value = 0
118  };
119  };
120 
122  struct TrueCase {
123 
124  enum Value {
125  value = 1
126  };
127  typedef meta::True type;
128  };
130  struct FalseCase {
131 
132  enum Values {
133  value = 0
134  };
135  typedef meta::False type;
136  };
138  template<int N>
139  struct Int {
140 
141  enum Value {
142  value = N
143  };
144  };
146  template<size_t N>
147  struct SizeT {
148 
149  enum Value {
150  value = N
151  };
152  };
154  template < bool T_BOOL> struct Bool;
156  template < > struct Bool < true > : meta::TrueCase {
157  };
159  template < > struct Bool < false > : meta::FalseCase {
160  };
162  template<bool T_BOOL_A, bool T_BOOL_B>
163  struct Or;
165  template < > struct Or < true, true > : meta::TrueCase {
166  };
168  template < > struct Or < true, false > : meta::TrueCase {
169  };
171  template < > struct Or < false, true > : meta::TrueCase {
172  };
174  template < > struct Or < false, false > : meta::FalseCase {
175  };
177  template<bool T_BOOL>
178  struct Not;
180  template<>
181  struct Not<true> : meta::FalseCase {
182  };
184  template<>
185  struct Not<false> : meta::TrueCase {
186  };
188  template<bool T_BOOL_A, bool T_BOOL_B>
189  struct And;
191  template < > struct And < true, true > : meta::TrueCase {
192  };
194  template < > struct And < true, false > : meta::FalseCase {
195  };
197  template < > struct And < false, true > : meta::FalseCase {
198  };
200  template < > struct And < false, false > : meta::FalseCase {
201  };
203  template<bool T_Bool, class T_True, class T_False>
204  struct If;
206  template<class T_True, class T_False>
207  struct If < true, T_True, T_False> {
208  typedef T_True type;
209  };
211  template<class T_True, class T_False>
212  struct If < false, T_True, T_False> {
213  typedef T_False type;
214  };
216  template<bool T_Bool, class MetaFunctionTrue, class MetaFunctionFalse>
217  struct EvalIf : public meta::If<T_Bool, MetaFunctionTrue, MetaFunctionFalse>::type {
218  };
220  template<size_t I>
221  struct Decrement{
222  typedef SizeT< I-1 > type;
223  enum Values{
224  value=I-1
225  };
226  };
228  template<size_t I>
229  struct Increment{
230  typedef SizeT< I+1 > type;
231  enum Values{
232  value=I+1
233  };
234  };
236  #define OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO(OPERATOR_SYMBOL,CLASS_NAME,RETURN_CLASS_TYPE) \
237  template<size_t A,size_t B> \
238  struct CLASS_NAME{ \
239  typedef typename Bool< (A OPERATOR_SYMBOL B) >::type type; \
240  enum Values{ \
241  value=RETURN_CLASS_TYPE < (A OPERATOR_SYMBOL B) >::value \
242  }; \
243  }
244 
246  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( + , Plus , meta::SizeT );
248  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( - , Minus , meta::SizeT );
250  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( * , Multiplies , meta::SizeT );
252  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( == , EqualNumber , meta::Bool );
254  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( > , BiggerNumber , meta::Bool );
256  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( >= , BiggerOrEqualNumber , meta::Bool );
258  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( < , SmallerNumber , meta::Bool );
260  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( <= , SmallerOrEqualNumber , meta::Bool );
262  template< size_t A,size_t B>
263  struct MinimumNumber{
264  enum Value{
265  value= meta::If<
266  SmallerNumber<A,B>::value,
267  SizeT<A>,
268  SizeT<B>
269  >::type::value
270  };
271  };
272 
274  template<class T, class U>
275  struct Compare : FalseCase {
276  };
278  template<class T>
279  struct Compare<T, T> : TrueCase {
280  };
282  template<class T>
283  struct InvalidType {
284  typedef T type;
285  };
287  template<class T>
288  struct IsInvalidType: opengm::meta::FalseCase {
289  };
291  template<class T>
292  struct IsInvalidType< InvalidType< T > > : opengm::meta::TrueCase {
293  };
294 
296  template<class T>
297  struct IsFactor : meta::FalseCase {
298  };
300  template<class T>
301  struct IsFactor<opengm::Factor<T> > : opengm::meta::TrueCase {
302  };
303 
305  template<class T>
306  struct IsIndependentFactor : opengm::meta::FalseCase {
307  };
309  template<class T,class I,class L>
310  struct IsIndependentFactor<opengm::IndependentFactor<T,I,L> > : opengm::meta::TrueCase {
311  };
313  template<class T>struct IsVoid : meta::FalseCase {
314  };
316  template< > struct IsVoid<void> : meta::TrueCase {
317  };
319  template<class T> struct IsReference : meta::FalseCase {
320  };
322  template<class T> struct IsReference<const T &> : meta::FalseCase {
323  };
325  template<class T> struct IsReference<T&> : meta::TrueCase {
326  };
328  template<class T> struct IsConstReference : meta::FalseCase {
329  };
331  template<class T> struct IsConstReference< T &> : meta::FalseCase {
332  };
334  template<class T> struct IsConstReference<const T&> : meta::TrueCase {
335  };
337  template <typename T>
338  struct RemoveReference {
339  typedef T type;
340  };
342  template <typename T>
343  struct RemoveReference<T&> {
344  typedef T type;
345  };
347  template <typename T>
348  struct RemoveConst {
349  typedef T type;
350  };
352  template <typename T>
353  struct RemoveConst<const T> {
354  typedef T type;
355  };
357  template<class T> struct AddReference {
358  typedef typename meta::If <
359  meta::Or <
360  meta::IsReference<T>::value,
361  meta::IsConstReference<T>::value
362  >::value,
363  T,
364  T &
365  >::type type;
366  };
368  template<class T> struct AddConstReference {
369  typedef typename meta::If
370  <
371  meta::IsConstReference<T>::value,
372  T,
373  typename meta::If <
374  meta::IsReference<T>::value,
375  typename meta::RemoveReference<T>::type const &,
376  T const &
377  >::type
378  >::type type;
379  };
381  template<class T_List>
382  struct LengthOfTypeList {
383  typedef meta::Int < 1 + LengthOfTypeList<typename T_List::TailType>::type::value> type;
384  enum {
385  value = type::value
386  };
387  };
389  template< >
390  struct LengthOfTypeList<meta::ListEnd> {
391  typedef meta::Int < 0 > type;
392 
393  enum {
394  value = 0
395  };
396  };
398  template<class T_List, unsigned int Index>
399  struct TypeAtTypeList {
400  typedef typename TypeAtTypeList<typename T_List::TailType, Index - 1 > ::type type;
401  };
403  template<class T_List>
404  struct TypeAtTypeList<T_List, 0 > {
405  typedef typename T_List::HeadType type;
406  };
408  template<class T_List, unsigned int Index, class T_DefaultType>
409  struct TypeAtTypeListSave
410  : meta::EvalIf<
411  meta::LengthOfTypeList<T_List>::value >= Index ? true : false,
412  meta::TypeAtTypeList<T_List, Index>,
413  meta::Self<T_DefaultType>
414  >::type {
415  };
416 
418  template<class T_Head, class T_Tail>
419  struct TypeList {
420  typedef meta::ListEnd ListEnd;
421  typedef T_Head HeadType;
422  typedef T_Tail TailType;
423  };
425  template
426  <
427  class T1,
428  class T2 = opengm::meta::ListEnd,
429  class T3 = opengm::meta::ListEnd,
430  class T4 = opengm::meta::ListEnd,
431  class T5 = opengm::meta::ListEnd,
432  class T6 = opengm::meta::ListEnd,
433  class T7 = opengm::meta::ListEnd,
434  class T8 = opengm::meta::ListEnd,
435  class T9 = opengm::meta::ListEnd,
436  class T10 = opengm::meta::ListEnd,
437  class T11 = opengm::meta::ListEnd,
438  class T12 = opengm::meta::ListEnd,
439  class T13 = opengm::meta::ListEnd,
440  class T14 = opengm::meta::ListEnd,
441  class T15 = opengm::meta::ListEnd
442  >
443  struct TypeListGenerator {
444  typedef opengm::meta::TypeList<T1, typename TypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
445  };
447  template< >
448  struct TypeListGenerator<opengm::meta::ListEnd> {
449  typedef opengm::meta::ListEnd type;
450  };
451 
453  template<bool B_IsTrue, class T_TrueType>
454  struct SwitchCase {
455  typedef T_TrueType type;
456 
457  struct Case : opengm::meta::Bool<B_IsTrue> {
458  };
459  };
460 
462  template <class T_List, class T_DefaultCase = opengm::meta::EmptyType >
463  struct Switch {
464  typedef typename opengm::meta::EvalIf
465  <
466  opengm::meta::TypeAtTypeList<T_List, 0 > ::type::Case::value,
467  typename opengm::meta::TypeAtTypeList<T_List, 0 >::type,
468  Switch<typename T_List::TailType, T_DefaultCase>
469  >::type type;
470  };
472  template<class T_DefaultCase>
473  struct Switch<opengm::meta::ListEnd, T_DefaultCase> {
474  typedef T_DefaultCase type;
475  };
477  template<class T> struct IsPtr : opengm::meta::FalseCase {
478  };
480  template<class T> struct IsPtr<T * const> : opengm::meta::FalseCase {
481  };
483  template<class T> struct IsPtr<T * > : opengm::meta::TrueCase {
484  };
486  template<class T> struct IsConstPtr : opengm::meta::FalseCase {
487  };
489  template<class T> struct IsConstPtr<T * > : opengm::meta::FalseCase {
490  };
492  template<class T> struct IsConstPtr<T * const > : opengm::meta::TrueCase {
493  };
495  template<class T> struct IsConst : opengm::meta::FalseCase {
496  };
498  template<class T> struct IsConst< const T> : opengm::meta::TrueCase {
499  };
501  template<class T>
502  struct IsFundamental {
503  typedef typename opengm::meta::Or <
504  std::numeric_limits< typename RemoveConst<T>::type >::is_specialized,
505  opengm::meta::IsVoid< typename RemoveConst<T>::type >::value
506  >::type type;
507 
508  enum Value{
509  value = type::value
510  };
511  };
513  template <class T>
514  struct IsFloatingPoint :
515  opengm::meta::Bool<
516  opengm::meta::Compare<T, float >::value ||
517  opengm::meta::Compare<T, const float >::value ||
518  opengm::meta::Compare<T, double >::value ||
519  opengm::meta::Compare<T, const double >::value ||
520  opengm::meta::Compare<T, long double >::value ||
521  opengm::meta::Compare<T, const long double >::value
522  > {
523  };
525  template<class T>
526  struct TypeInfo {
527 
528  struct IsFundamental : opengm::meta::IsFundamental<T> {
529  };
530 
531  struct IsFloatingPoint : opengm::meta::IsFloatingPoint<T> {
532  };
533 
534  struct IsConst : opengm::meta::IsConst<T> {
535  };
536 
537  struct IsConstReference : opengm::meta::IsConstReference<T> {
538  };
539 
540  struct IsReference : opengm::meta::IsReference<T> {
541  };
542 
543  struct IsPtr : opengm::meta::IsPtr<T> {
544  };
545 
546  struct IsConstPtr : opengm::meta::IsConstPtr<T> {
547  };
548  };
550  template<class T>
551  struct IsTypeList : meta::FalseCase{};
553  template<class TH,class TT>
554  struct IsTypeList< meta::TypeList<TH,TT> > : meta::TrueCase{};
556  template<class T>
557  struct TypeListFromMaybeTypeList{
558  typedef meta::TypeList<T,meta::ListEnd> type;
559  };
561  template<class TH,class TT>
562  struct TypeListFromMaybeTypeList< meta::TypeList<TH,TT> > {
563  typedef meta::TypeList<TH,TT> type;
564  };
566  template<class TL,class FrontType>
567  struct FrontInsert{
568  typedef meta::TypeList<FrontType,TL> type;
569  };
571  template<class TL,class TYPE>
572  struct BackInsert;
574  template<class THEAD,class TTAIL,class TYPE>
575  struct BackInsert<TypeList<THEAD,TTAIL> ,TYPE>{
576  typedef TypeList<
577  THEAD,
578  typename meta::BackInsert<
579  TTAIL ,
580  TYPE
581  >::type
582  > type;
583  };
585  template<class TYPE>
586  struct BackInsert<ListEnd,TYPE>{
587  typedef meta::TypeList<TYPE,ListEnd> type;
588  };
590  template<class TL,class TypeToFindx>
591  struct GetIndexInTypeList;
593  template<class THEAD,class TTAIL,class TypeToFind>
594  struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>{
595  enum Value{
596  value=GetIndexInTypeList<TTAIL,TypeToFind >::value+1
597  };
598  typedef meta::SizeT<GetIndexInTypeList<TTAIL,TypeToFind >::type::value +1> type;
599  };
601  template<class THEAD,class TTAIL>
602  struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD >{
603  enum Value{
604  value=0
605  };
606  typedef meta::SizeT<0> type;
607  };
609  template<class TL,class TypeToFindx,size_t NOT_FOUND_INDEX>
610  struct GetIndexInTypeListSafely;
612  template<class THEAD,class TTAIL,class TypeToFind,size_t NOT_FOUND_INDEX>
613  struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,TypeToFind,NOT_FOUND_INDEX>{
614  enum Value{
615  value=GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::value+1
616  };
617  typedef meta::SizeT<GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::type::value +1> type;
618  };
620  template<class THEAD,class TTAIL,size_t NOT_FOUND_INDEX>
621  struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,THEAD,NOT_FOUND_INDEX >{
622  enum Value{
623  value=0
624  };
625  typedef meta::SizeT<0> type;
626  };
628  template<class TYPE_TO_FIND,size_t NOT_FOUND_INDEX>
629  struct GetIndexInTypeListSafely<meta::ListEnd,TYPE_TO_FIND,NOT_FOUND_INDEX >{
630  enum Value{
631  value=NOT_FOUND_INDEX
632  };
633  typedef meta::SizeT<NOT_FOUND_INDEX> type;
634  };
636  template <class TL,class T>
637  struct DeleteTypeInTypeList;
639  template <class T>
640  struct DeleteTypeInTypeList<ListEnd,T> {
641  typedef ListEnd type;
642  };
644  template <class T,class TTail>
645  struct DeleteTypeInTypeList<TypeList<T,TTail>,T> {
646  typedef TTail type;
647  };
649  template <class THead,class TTail, class T>
650  struct DeleteTypeInTypeList<TypeList<THead,TTail>,T> {
651  typedef TypeList<THead, typename DeleteTypeInTypeList<TTail,T>::type> type;
652  };
654  template<class TL,class TypeToFindx>
655  struct HasTypeInTypeList;
657  template<class THEAD,class TTAIL,class TypeToFind>
658  struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>
659  {
660  enum Value{
661  value=HasTypeInTypeList<TTAIL,TypeToFind >::value
662  };
663  typedef HasTypeInTypeList< TTAIL,TypeToFind> type;
664  };
665 
667  template<class TL,class TSL,size_t SIZE,class NOT_FOUND>
668  struct FindSizedType;
670  template<class TLH,class TLT,class TSLH,class TSLT,size_t SIZE,class NOT_FOUND>
671  struct FindSizedType<meta::TypeList<TLH,TLT>,meta::TypeList<TSLH,TSLT>,SIZE,NOT_FOUND>{
672  typedef typename FindSizedType<TLT,TSLT,SIZE,NOT_FOUND >::type type;
673  };
675  template<class TLH ,class TLT,class TSLT,size_t SIZE,class NOT_FOUND>
676  struct FindSizedType< meta::TypeList<TLH,TLT>,meta::TypeList< meta::SizeT<SIZE> ,TSLT>,SIZE,NOT_FOUND >{
677  typedef TLH type;
678  };
680  template<size_t SIZE,class NOT_FOUND>
681  struct FindSizedType< meta::ListEnd,meta::ListEnd,SIZE,NOT_FOUND >{
682  typedef NOT_FOUND type;
683  };
685  template<class TL,class OTHER_TL>
686  struct MergeTypeLists;
688  template<class THEAD,class TTAIL,class OTHER_TL>
689  struct MergeTypeLists<meta::TypeList<THEAD,TTAIL>,OTHER_TL>
690  {
691  typedef meta::TypeList<
692  THEAD,
693  typename MergeTypeLists<TTAIL,OTHER_TL>::type
694  > type;
695  };
697  template<class OTHER_TL>
698  struct MergeTypeLists<meta::ListEnd,OTHER_TL>
699  {
700  typedef OTHER_TL type;
701  };
703  template<class THEAD,class TTAIL>
704  struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD > : meta::TrueCase{
705  };
707  template<class TypeToFindx>
708  struct HasTypeInTypeList<meta::ListEnd,TypeToFindx> : meta::FalseCase{
709  };
714  template<class TL,class TYPE>
715  struct InsertInTypeListOrMoveToEnd{
716  typedef typename meta::If<
717  meta::HasTypeInTypeList<
718  TL,
719  TYPE
720  >::value,
721  typename meta::BackInsert<
722  typename DeleteTypeInTypeList< TL,TYPE >::type,
723  TYPE
724  >::type,
725  typename meta::BackInsert<
726  TL,
727  TYPE
728  >::type
729  >::type type;
730  };
732  template<class TL, class OTHER_TL>
733  struct MergeTypeListsWithoutDups;
735  template<class TL, class THEAD, class TTAIL>
736  struct MergeTypeListsWithoutDups<TL, meta::TypeList<THEAD, TTAIL> > {
737  typedef typename MergeTypeListsWithoutDups<
738  typename meta::InsertInTypeListOrMoveToEnd<TL, THEAD>::type,
739  TTAIL
740  >::type type;
741  };
743  template<class TL>
744  struct MergeTypeListsWithoutDups<TL, meta::ListEnd> {
745  typedef TL type;
746  };
748  template<class TL>
749  struct HasDuplicatesInTypeList;
751  template<class THEAD,class TTAIL>
752  struct HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >{
753  typedef typename meta::EvalIf<
754  HasTypeInTypeList<TTAIL,THEAD>::value,
755  meta::Bool<true>,
756  HasDuplicatesInTypeList< TTAIL>
757  >::type type;
758 
759  enum Value{
760  value= HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >::type::value
761  };
762  };
764  template< >
765  struct HasDuplicatesInTypeList<meta::ListEnd> : meta::FalseCase{
766  };
768  template<class MAYBE_TYPELIST,class EXPLICIT_FUNCTION_TYPE,bool EDITABLE>
769  struct GenerateFunctionTypeList{
770  typedef typename meta::TypeListFromMaybeTypeList<MAYBE_TYPELIST>::type StartTypeList;
771  typedef typename meta::If<
772  EDITABLE,
773  typename InsertInTypeListOrMoveToEnd<StartTypeList,EXPLICIT_FUNCTION_TYPE>::type,
774  StartTypeList
775  >::type type;
776 
777  };
779  template<class T>
780  struct CallTraits {
781  typedef T ValueType;
782  typedef T value_type;
783  typedef typename opengm::meta::AddReference<T>::type reference;
784  typedef typename opengm::meta::AddConstReference<T>::type const_reference;
785  typedef typename opengm::meta::If <
786  opengm::meta::TypeInfo<T>::IsFundamental::value,
787  typename opengm::meta::RemoveConst<T>::type const,
788  typename opengm::meta::AddConstReference<T>::type
789  >::type
790  param_type;
791  };
793  template<class TList ,template <class> class InstanceUnitType,class TListSrc>
794  class FieldHelper;
795  template<class ListHead,class ListTail,template <class> class InstanceUnitType,class TListSrc>
796  class FieldHelper< opengm::meta::TypeList<ListHead,ListTail> ,InstanceUnitType,TListSrc>
797  : public FieldHelper<ListHead,InstanceUnitType,TListSrc>,
798  public FieldHelper<ListTail,InstanceUnitType,TListSrc>{
799  };
800  template< class ListTail ,template <class> class InstanceUnitType,class TListSrc>
801  class FieldHelper
802  : public InstanceUnitType<ListTail>{
803  };
804  template< template <class> class InstanceUnitType,class TListSrc>
805  class FieldHelper<opengm::meta::ListEnd,InstanceUnitType,TListSrc>{
806  };
808  template<class TList ,template <class> class InstanceUnitType>
809  class Field
810  : public FieldHelper<TList,InstanceUnitType,TList>{
811  public:
812  public:
813  template <typename T>
814  struct RebingByType{
815  typedef InstanceUnitType<T> type;
816  };
817  template <size_t Index>
818  struct RebingByIndex{
819  typedef InstanceUnitType<typename TypeAtTypeList<TList,Index>::type > type;
820  };
821  };
823  template<class TList ,class TYPE2,template <class ,class > class InstanceUnitType,class TListSrc>
824  class Field2Helper;
826  template<class ListHead,class ListTail,class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
827  class Field2Helper< opengm::meta::TypeList<ListHead,ListTail> ,TYPE2,InstanceUnitType,TListSrc>
828  : public Field2Helper<ListHead,TYPE2,InstanceUnitType,TListSrc>,
829  public Field2Helper<ListTail,TYPE2,InstanceUnitType,TListSrc>{
830  };
832  template< class ListTail ,class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
833  class Field2Helper
834  : public InstanceUnitType<ListTail,TYPE2>{
835  };
837  template< class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
838  class Field2Helper<opengm::meta::ListEnd,TYPE2,InstanceUnitType,TListSrc>{
839  };
841  template<class TList,class TYPE2 ,template <class,class> class InstanceUnitType>
842  class Field2
843  :
844  public Field2Helper<TList,TYPE2,InstanceUnitType,TList>{
845  public:
846  public:
847  template <typename T>
848  struct RebingByType{
849  typedef InstanceUnitType<T,TYPE2> type;
850  };
851  template <size_t Index>
852  struct RebingByIndex{
853  typedef InstanceUnitType<typename TypeAtTypeList<TList,Index>::type,TYPE2 > type;
854  };
855  };
857  struct FieldAccess{
858  template<size_t Index,class IG>
859  static inline typename IG::template RebingByIndex<Index>::type &
860  byIndex
861  (
862  IG & instanceGenerator
863  ) {
864  return instanceGenerator;
865  }
866 
867  template<size_t Index,class IG>
868  static inline const typename IG::template RebingByIndex<Index>::type &
869  byIndex
870  (
871  const IG & instanceGenerator
872  ) {
873  return instanceGenerator;
874  }
875 
876  template<class T,class IG>
877  static inline typename IG::template RebingByType<T>::type &
878  byType
879  (
880  IG & instanceGenerator
881  ) {
882  return instanceGenerator;
883  }
884 
885  template<class T,class IG>
886  static inline const typename IG::template RebingByType<T>::type &
887  byType
888  (
889  const IG & instanceGenerator
890  ) {
891  return instanceGenerator;
892  }
893  };
895  template<class Factor,size_t FunctionIndex>
896  class GetFunctionFromFactor
897  {
898  typedef typename Factor::FunctionTypeList FunctionTypeList;
899  public:
900  typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
901  static inline const FunctionType & get(const Factor & factor) {
902  return factor. template function<FunctionIndex>();
903  }
904  static inline FunctionType & get( Factor & factor) {
905  return factor. template function<FunctionIndex>();
906  }
907  };
909  template<class Factor,size_t FunctionIndex>
910  class GetFunction;
912  template<class T,size_t FunctionIndex>
913  class GetFunction<opengm::Factor<T>,FunctionIndex >{
914  typedef typename Factor<T>::FunctionTypeList FunctionTypeList;
915  public:
916  typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
917 
918  static inline const FunctionType & get(const Factor<T> & factor) {
919  return factor. template function<FunctionIndex>();
920  };
921  static inline FunctionType & get(Factor<T> & factor) {
922  return factor. template function<FunctionIndex>();
923  };
924  };
926  template<class T,class I,class L,size_t FunctionIndex>
927  class GetFunction<IndependentFactor<T,I,L>,FunctionIndex >{
928  public:
929  typedef typename IndependentFactor<T,I,L>::FunctionType FunctionType;
930  static inline const FunctionType & get(const IndependentFactor<T,I,L> & factor) {
931  return factor.template function<0>();
932  };
933  static inline FunctionType & get(IndependentFactor<T,I,L> & factor) {
934  return factor.template function<0>();
935  };
936  };
938  template<class Factor>
939  class GetFunctionTypeIndex;
941  template<class T>
942  class GetFunctionTypeIndex<opengm::Factor<T> >{
943  public:
944  static inline size_t get(const opengm::Factor<T> & factor) {
945  return factor.functionType();
946  }
947  static inline size_t get(opengm::Factor<T> & factor) {
948  return factor.functionType();
949  }
950  };
952  template<class T,class I,class L>
953  class GetFunctionTypeIndex<opengm::IndependentFactor<T,I,L> >{
954  public:
955  static inline size_t get(const opengm::IndependentFactor<T,I,L> & factor) {
956  return 0;
957  }
958  static inline size_t get( opengm::IndependentFactor<T,I,L> & factor) {
959  return 0;
960  }
961  };
963  template <class T>
964  class IsField : opengm::meta::FalseCase{};
966  template<class TList ,template <class> class InstanceUnitType>
967  class IsField< meta::Field<TList,InstanceUnitType> > : opengm::meta::TrueCase{};
969  struct ErrorMessage{
970  struct WRONG_FUNCTION_TYPE;
971  };
973  template <class MSG>
974  struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_;
975  template < >
976  struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_<meta::EmptyType >{
977  };
979  template<bool>
980  class Assert;
981  template<>
982  class Assert<true>{
983  };
985  template<class TLIST,size_t INITIAL_VALUE, template <size_t, size_t> class ACCUMULATOR>
986  class Accumulate;
988  template<class TLIST_HEAD,class TLIST_TAIL,size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
989  class Accumulate<meta::TypeList<TLIST_HEAD,TLIST_TAIL>,INITIAL_VALUE ,ACCUMULATOR >{
990  enum Value{
991  value=Accumulate<
992  TLIST_TAIL,
993  ACCUMULATOR <
994  INITIAL_VALUE,
995  TLIST_HEAD::value
996  >::value ,
997  ACCUMULATOR
998  >::value
999  };
1000  typedef SizeT<
1001  Accumulate<
1002  TLIST_TAIL ,
1003  ACCUMULATOR<
1004  INITIAL_VALUE,
1005  TLIST_HEAD::value
1006  >::value ,
1007  ACCUMULATOR
1008  >::value
1009  > type;
1010  };
1012  template<size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
1013  class Accumulate<meta::ListEnd,INITIAL_VALUE ,ACCUMULATOR >{
1014  enum Value{
1015  value=INITIAL_VALUE
1016  };
1017  typedef SizeT<INITIAL_VALUE> type;
1018  };
1019 
1020  template<class T>
1021  struct PromoteToFloatingPoint{
1022  typedef typename meta::If<
1023  meta::IsFloatingPoint<T>::value ,
1024  T,
1025  float
1026  >::type type;
1027  };
1028 
1029  // metaprogramming check if BASE is base class of DERIVED
1030  template <class BASE, class DERIVED>
1031  struct IsBaseOf {
1032  typedef char yes[1];
1033  typedef char no[2];
1034 
1035  static yes& test(BASE*);
1036  static no& test(...);
1037 
1038  static DERIVED* get(void);
1039 
1040  enum Value{
1041  value = (sizeof(test(get())) == sizeof(yes))
1042  };
1043  };
1044 
1045  // metaprogramming check if T is complete type
1046  template <class T>
1047  struct IsCompleteType {
1048  typedef char yes[1];
1049  typedef char no[2];
1050 
1051  template <class T1>
1052  static yes& test(int(*)[sizeof(T1)]);
1053  template <class T1>
1054  static no& test(...);
1055 
1056  enum Value{
1057  value = (sizeof(test<T>(0)) == sizeof(yes))
1058  };
1059  };
1060  // constraint function typelist
1061  // metaprogramming get linear constraint function typelist
1062  // note: LinearConstraintFunctionTypeList might return an empty type list containing only meta::ListEnd elements.
1063  // This happens if TL does not contain any linear constraint function
1064  template <class TL>
1065  struct GetLinearConstraintFunctionTypeList;
1066 
1067  // metaprogramming get linear constraint function typelist
1068  template<class THEAD,class TTAIL>
1069  struct GetLinearConstraintFunctionTypeList<TypeList<THEAD,TTAIL> > {
1070  typedef TypeList<THEAD, typename GetLinearConstraintFunctionTypeList<TTAIL>::type > true_type;
1071  typedef typename TypeListFromMaybeTypeList<typename GetLinearConstraintFunctionTypeList<TTAIL>::type>::type false_type;
1072 
1073  template <class FUNCTION, bool IS_COMPLETE_TYPE>
1074  struct IsLinearConstraintFunction {
1075  typedef false_type type;
1076  };
1077 
1078  template <class FUNCTION>
1079  struct IsLinearConstraintFunction<FUNCTION, true> {
1080  typedef typename If<IsBaseOf<opengm::LinearConstraintFunctionBase<FUNCTION>, FUNCTION>::value, true_type, false_type>::type type;
1081  };
1082  typedef IsCompleteType<opengm::LinearConstraintFunctionTraits<THEAD> > IsCompleteLinearConstraintFunction;
1083  // add THEAD only if it is derived from LinearConstraintBase<THEAD>
1084  typedef typename IsLinearConstraintFunction<THEAD, IsCompleteLinearConstraintFunction::value>::type type;
1085  };
1086 
1087  // metaprogramming get linear constraint function typelist
1088  template<>
1089  struct GetLinearConstraintFunctionTypeList<ListEnd> {
1090  typedef ListEnd type;
1091  };
1092  } // namespace meta
1093 
1094 
1104  template
1105  <
1106  class T1,
1107  class T2 = meta::ListEnd,
1108  class T3 = meta::ListEnd,
1109  class T4 = meta::ListEnd,
1110  class T5 = meta::ListEnd,
1111  class T6 = meta::ListEnd,
1112  class T7 = meta::ListEnd,
1113  class T8 = meta::ListEnd,
1114  class T9 = meta::ListEnd,
1115  class T10 = meta::ListEnd,
1116  class T11 = meta::ListEnd,
1117  class T12 = meta::ListEnd,
1118  class T13 = meta::ListEnd,
1119  class T14 = meta::ListEnd,
1120  class T15 = meta::ListEnd
1121  >
1122  struct FunctionTypeListGenerator {
1123  typedef meta::TypeList<T1, typename FunctionTypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
1124  };
1125 
1126  template< >
1127  struct FunctionTypeListGenerator<meta::ListEnd> {
1128  typedef meta::ListEnd type;
1129  };
1130 
1132 
1133 } // namespace opengm
1134 
1135 #endif // #ifndef OPENGM_METAPROGRAMMING
1136 
The OpenGM namespace.
Definition: config.hxx:43
Factor (with corresponding function and variable indices), independent of a GraphicalModel.
GraphicalModelType::FunctionTypeList FunctionTypeList
Abstraction (wrapper class) of factors, independent of the function used to implement the factor...