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 
54  class LinearConstraintFunctionTraitsUndefined;
55 
57  namespace meta {
59  template< template < typename > class TO_BIND >
60  struct Bind1{
61  template<class BIND_ARG_0>
62  struct Bind{
63  typedef TO_BIND<BIND_ARG_0> type;
64  };
65  };
67  template< template < typename ,typename > class TO_BIND >
68  struct Bind2{
69  template<class BIND_ARG_0, class BIND_ARG_1>
70  struct Bind{
71  typedef TO_BIND<BIND_ARG_0, BIND_ARG_1> type;
72  };
73  };
75  template< template < typename ,typename, typename > class TO_BIND >
76  struct Bind3{
77  template<class BIND_ARG_0, class BIND_ARG_1, class BIND_ARG_2>
78  struct Bind{
79  typedef TO_BIND<BIND_ARG_0, BIND_ARG_1, BIND_ARG_2> type;
80  };
81  };
82 
88  template<class T>
89  struct ApplyMetaFunction {
90  typedef typename T::type type;
91  };
95  template<class T>
96  struct Self {
97  typedef T type;
98  };
100  struct EmptyType {
101  };
103  struct NullType {
104  };
106  struct ListEnd {
107  };
109  struct True {
110 
111  enum Value {
112  value = 1
113  };
114  };
116  struct False {
117 
118  enum Value {
119  value = 0
120  };
121  };
122 
124  struct TrueCase {
125 
126  enum Value {
127  value = 1
128  };
129  typedef meta::True type;
130  };
132  struct FalseCase {
133 
134  enum Values {
135  value = 0
136  };
137  typedef meta::False type;
138  };
140  template<int N>
141  struct Int {
142 
143  enum Value {
144  value = N
145  };
146  };
148  template<size_t N>
149  struct SizeT {
150 
151  enum Value {
152  value = N
153  };
154  };
156  template < bool T_BOOL> struct Bool;
158  template < > struct Bool < true > : meta::TrueCase {
159  };
161  template < > struct Bool < false > : meta::FalseCase {
162  };
164  template<bool T_BOOL_A, bool T_BOOL_B>
165  struct Or;
167  template < > struct Or < true, true > : meta::TrueCase {
168  };
170  template < > struct Or < true, false > : meta::TrueCase {
171  };
173  template < > struct Or < false, true > : meta::TrueCase {
174  };
176  template < > struct Or < false, false > : meta::FalseCase {
177  };
179  template<bool T_BOOL>
180  struct Not;
182  template<>
183  struct Not<true> : meta::FalseCase {
184  };
186  template<>
187  struct Not<false> : meta::TrueCase {
188  };
190  template<bool T_BOOL_A, bool T_BOOL_B>
191  struct And;
193  template < > struct And < true, true > : meta::TrueCase {
194  };
196  template < > struct And < true, false > : meta::FalseCase {
197  };
199  template < > struct And < false, true > : meta::FalseCase {
200  };
202  template < > struct And < false, false > : meta::FalseCase {
203  };
205  template<bool T_Bool, class T_True, class T_False>
206  struct If;
208  template<class T_True, class T_False>
209  struct If < true, T_True, T_False> {
210  typedef T_True type;
211  };
213  template<class T_True, class T_False>
214  struct If < false, T_True, T_False> {
215  typedef T_False type;
216  };
218  template<bool T_Bool, class MetaFunctionTrue, class MetaFunctionFalse>
219  struct EvalIf : public meta::If<T_Bool, MetaFunctionTrue, MetaFunctionFalse>::type {
220  };
222  template<size_t I>
223  struct Decrement{
224  typedef SizeT< I-1 > type;
225  enum Values{
226  value=I-1
227  };
228  };
230  template<size_t I>
231  struct Increment{
232  typedef SizeT< I+1 > type;
233  enum Values{
234  value=I+1
235  };
236  };
238  #define OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO(OPERATOR_SYMBOL,CLASS_NAME,RETURN_CLASS_TYPE) \
239  template<size_t A,size_t B> \
240  struct CLASS_NAME{ \
241  typedef typename Bool< (A OPERATOR_SYMBOL B) >::type type; \
242  enum Values{ \
243  value=RETURN_CLASS_TYPE < (A OPERATOR_SYMBOL B) >::value \
244  }; \
245  }
246 
248  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( + , Plus , meta::SizeT );
250  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( - , Minus , meta::SizeT );
252  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( * , Multiplies , meta::SizeT );
254  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( == , EqualNumber , meta::Bool );
256  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( > , BiggerNumber , meta::Bool );
258  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( >= , BiggerOrEqualNumber , meta::Bool );
260  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( < , SmallerNumber , meta::Bool );
262  OPENGM_METAPROGRAMMING_BINARY_OPERATOR_GENERATOR_MACRO( <= , SmallerOrEqualNumber , meta::Bool );
264  template< size_t A,size_t B>
265  struct MinimumNumber{
266  enum Value{
267  value= meta::If<
268  SmallerNumber<A,B>::value,
269  SizeT<A>,
270  SizeT<B>
271  >::type::value
272  };
273  };
274 
276  template<class T, class U>
277  struct Compare : FalseCase {
278  };
280  template<class T>
281  struct Compare<T, T> : TrueCase {
282  };
284  template<class T>
285  struct InvalidType {
286  typedef T type;
287  };
289  template<class T>
290  struct IsInvalidType: opengm::meta::FalseCase {
291  };
293  template<class T>
294  struct IsInvalidType< InvalidType< T > > : opengm::meta::TrueCase {
295  };
296 
298  template<class T>
299  struct IsFactor : meta::FalseCase {
300  };
302  template<class T>
303  struct IsFactor<opengm::Factor<T> > : opengm::meta::TrueCase {
304  };
305 
307  template<class T>
308  struct IsIndependentFactor : opengm::meta::FalseCase {
309  };
311  template<class T,class I,class L>
312  struct IsIndependentFactor<opengm::IndependentFactor<T,I,L> > : opengm::meta::TrueCase {
313  };
315  template<class T>struct IsVoid : meta::FalseCase {
316  };
318  template< > struct IsVoid<void> : meta::TrueCase {
319  };
321  template<class T> struct IsReference : meta::FalseCase {
322  };
324  template<class T> struct IsReference<const T &> : meta::FalseCase {
325  };
327  template<class T> struct IsReference<T&> : meta::TrueCase {
328  };
330  template<class T> struct IsConstReference : meta::FalseCase {
331  };
333  template<class T> struct IsConstReference< T &> : meta::FalseCase {
334  };
336  template<class T> struct IsConstReference<const T&> : meta::TrueCase {
337  };
339  template <typename T>
340  struct RemoveReference {
341  typedef T type;
342  };
344  template <typename T>
345  struct RemoveReference<T&> {
346  typedef T type;
347  };
349  template <typename T>
350  struct RemoveConst {
351  typedef T type;
352  };
354  template <typename T>
355  struct RemoveConst<const T> {
356  typedef T type;
357  };
359  template<class T> struct AddReference {
360  typedef typename meta::If <
361  meta::Or <
362  meta::IsReference<T>::value,
363  meta::IsConstReference<T>::value
364  >::value,
365  T,
366  T &
367  >::type type;
368  };
370  template<class T> struct AddConstReference {
371  typedef typename meta::If
372  <
373  meta::IsConstReference<T>::value,
374  T,
375  typename meta::If <
376  meta::IsReference<T>::value,
377  typename meta::RemoveReference<T>::type const &,
378  T const &
379  >::type
380  >::type type;
381  };
383  template<class T_List>
384  struct LengthOfTypeList {
385  typedef meta::Int < 1 + LengthOfTypeList<typename T_List::TailType>::type::value> type;
386  enum {
387  value = type::value
388  };
389  };
391  template< >
392  struct LengthOfTypeList<meta::ListEnd> {
393  typedef meta::Int < 0 > type;
394 
395  enum {
396  value = 0
397  };
398  };
400  template<class T_List, unsigned int Index>
401  struct TypeAtTypeList {
402  typedef typename TypeAtTypeList<typename T_List::TailType, Index - 1 > ::type type;
403  };
405  template<class T_List>
406  struct TypeAtTypeList<T_List, 0 > {
407  typedef typename T_List::HeadType type;
408  };
410  template<class T_List, unsigned int Index, class T_DefaultType>
411  struct TypeAtTypeListSave
412  : meta::EvalIf<
413  meta::LengthOfTypeList<T_List>::value >= Index ? true : false,
414  meta::TypeAtTypeList<T_List, Index>,
415  meta::Self<T_DefaultType>
416  >::type {
417  };
418 
420  template<class T_Head, class T_Tail>
421  struct TypeList {
422  typedef meta::ListEnd ListEnd;
423  typedef T_Head HeadType;
424  typedef T_Tail TailType;
425  };
427  template
428  <
429  class T1,
430  class T2 = opengm::meta::ListEnd,
431  class T3 = opengm::meta::ListEnd,
432  class T4 = opengm::meta::ListEnd,
433  class T5 = opengm::meta::ListEnd,
434  class T6 = opengm::meta::ListEnd,
435  class T7 = opengm::meta::ListEnd,
436  class T8 = opengm::meta::ListEnd,
437  class T9 = opengm::meta::ListEnd,
438  class T10 = opengm::meta::ListEnd,
439  class T11 = opengm::meta::ListEnd,
440  class T12 = opengm::meta::ListEnd,
441  class T13 = opengm::meta::ListEnd,
442  class T14 = opengm::meta::ListEnd,
443  class T15 = opengm::meta::ListEnd
444  >
445  struct TypeListGenerator {
446  typedef opengm::meta::TypeList<T1, typename TypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
447  };
449  template< >
450  struct TypeListGenerator<opengm::meta::ListEnd> {
451  typedef opengm::meta::ListEnd type;
452  };
453 
455  template<bool B_IsTrue, class T_TrueType>
456  struct SwitchCase {
457  typedef T_TrueType type;
458 
459  struct Case : opengm::meta::Bool<B_IsTrue> {
460  };
461  };
462 
464  template <class T_List, class T_DefaultCase = opengm::meta::EmptyType >
465  struct Switch {
466  typedef typename opengm::meta::EvalIf
467  <
468  opengm::meta::TypeAtTypeList<T_List, 0 > ::type::Case::value,
469  typename opengm::meta::TypeAtTypeList<T_List, 0 >::type,
470  Switch<typename T_List::TailType, T_DefaultCase>
471  >::type type;
472  };
474  template<class T_DefaultCase>
475  struct Switch<opengm::meta::ListEnd, T_DefaultCase> {
476  typedef T_DefaultCase type;
477  };
479  template<class T> struct IsPtr : opengm::meta::FalseCase {
480  };
482  template<class T> struct IsPtr<T * const> : opengm::meta::FalseCase {
483  };
485  template<class T> struct IsPtr<T * > : opengm::meta::TrueCase {
486  };
488  template<class T> struct IsConstPtr : opengm::meta::FalseCase {
489  };
491  template<class T> struct IsConstPtr<T * > : opengm::meta::FalseCase {
492  };
494  template<class T> struct IsConstPtr<T * const > : opengm::meta::TrueCase {
495  };
497  template<class T> struct IsConst : opengm::meta::FalseCase {
498  };
500  template<class T> struct IsConst< const T> : opengm::meta::TrueCase {
501  };
503  template<class T>
504  struct IsFundamental {
505  typedef typename opengm::meta::Or <
506  std::numeric_limits< typename RemoveConst<T>::type >::is_specialized,
507  opengm::meta::IsVoid< typename RemoveConst<T>::type >::value
508  >::type type;
509 
510  enum Value{
511  value = type::value
512  };
513  };
515  template <class T>
516  struct IsFloatingPoint :
517  opengm::meta::Bool<
518  opengm::meta::Compare<T, float >::value ||
519  opengm::meta::Compare<T, const float >::value ||
520  opengm::meta::Compare<T, double >::value ||
521  opengm::meta::Compare<T, const double >::value ||
522  opengm::meta::Compare<T, long double >::value ||
523  opengm::meta::Compare<T, const long double >::value
524  > {
525  };
527  template<class T>
528  struct TypeInfo {
529 
530  struct IsFundamental : opengm::meta::IsFundamental<T> {
531  };
532 
533  struct IsFloatingPoint : opengm::meta::IsFloatingPoint<T> {
534  };
535 
536  struct IsConst : opengm::meta::IsConst<T> {
537  };
538 
539  struct IsConstReference : opengm::meta::IsConstReference<T> {
540  };
541 
542  struct IsReference : opengm::meta::IsReference<T> {
543  };
544 
545  struct IsPtr : opengm::meta::IsPtr<T> {
546  };
547 
548  struct IsConstPtr : opengm::meta::IsConstPtr<T> {
549  };
550  };
552  template<class T>
553  struct IsTypeList : meta::FalseCase{};
555  template<class TH,class TT>
556  struct IsTypeList< meta::TypeList<TH,TT> > : meta::TrueCase{};
558  template<class T>
559  struct TypeListFromMaybeTypeList{
560  typedef meta::TypeList<T,meta::ListEnd> type;
561  };
563  template<class TH,class TT>
564  struct TypeListFromMaybeTypeList< meta::TypeList<TH,TT> > {
565  typedef meta::TypeList<TH,TT> type;
566  };
568  template<class TL,class FrontType>
569  struct FrontInsert{
570  typedef meta::TypeList<FrontType,TL> type;
571  };
573  template<class TL,class TYPE>
574  struct BackInsert;
576  template<class THEAD,class TTAIL,class TYPE>
577  struct BackInsert<TypeList<THEAD,TTAIL> ,TYPE>{
578  typedef TypeList<
579  THEAD,
580  typename meta::BackInsert<
581  TTAIL ,
582  TYPE
583  >::type
584  > type;
585  };
587  template<class TYPE>
588  struct BackInsert<ListEnd,TYPE>{
589  typedef meta::TypeList<TYPE,ListEnd> type;
590  };
592  template<class TL,class TypeToFindx>
593  struct GetIndexInTypeList;
595  template<class THEAD,class TTAIL,class TypeToFind>
596  struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>{
597  enum Value{
598  value=GetIndexInTypeList<TTAIL,TypeToFind >::value+1
599  };
600  typedef meta::SizeT<GetIndexInTypeList<TTAIL,TypeToFind >::type::value +1> type;
601  };
603  template<class THEAD,class TTAIL>
604  struct GetIndexInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD >{
605  enum Value{
606  value=0
607  };
608  typedef meta::SizeT<0> type;
609  };
611  template<class TL,class TypeToFindx,size_t NOT_FOUND_INDEX>
612  struct GetIndexInTypeListSafely;
614  template<class THEAD,class TTAIL,class TypeToFind,size_t NOT_FOUND_INDEX>
615  struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,TypeToFind,NOT_FOUND_INDEX>{
616  enum Value{
617  value=GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::value+1
618  };
619  typedef meta::SizeT<GetIndexInTypeListSafely<TTAIL,TypeToFind,NOT_FOUND_INDEX >::type::value +1> type;
620  };
622  template<class THEAD,class TTAIL,size_t NOT_FOUND_INDEX>
623  struct GetIndexInTypeListSafely<meta::TypeList<THEAD,TTAIL>,THEAD,NOT_FOUND_INDEX >{
624  enum Value{
625  value=0
626  };
627  typedef meta::SizeT<0> type;
628  };
630  template<class TYPE_TO_FIND,size_t NOT_FOUND_INDEX>
631  struct GetIndexInTypeListSafely<meta::ListEnd,TYPE_TO_FIND,NOT_FOUND_INDEX >{
632  enum Value{
633  value=NOT_FOUND_INDEX
634  };
635  typedef meta::SizeT<NOT_FOUND_INDEX> type;
636  };
638  template <class TL,class T>
639  struct DeleteTypeInTypeList;
641  template <class T>
642  struct DeleteTypeInTypeList<ListEnd,T> {
643  typedef ListEnd type;
644  };
646  template <class T,class TTail>
647  struct DeleteTypeInTypeList<TypeList<T,TTail>,T> {
648  typedef TTail type;
649  };
651  template <class THead,class TTail, class T>
652  struct DeleteTypeInTypeList<TypeList<THead,TTail>,T> {
653  typedef TypeList<THead, typename DeleteTypeInTypeList<TTail,T>::type> type;
654  };
656  template<class TL,class TypeToFindx>
657  struct HasTypeInTypeList;
659  template<class THEAD,class TTAIL,class TypeToFind>
660  struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,TypeToFind>
661  {
662  enum Value{
663  value=HasTypeInTypeList<TTAIL,TypeToFind >::value
664  };
665  typedef HasTypeInTypeList< TTAIL,TypeToFind> type;
666  };
667 
669  template<class THEAD,class TTAIL>
670  struct HasTypeInTypeList<meta::TypeList<THEAD,TTAIL>,THEAD > : meta::TrueCase{
671  };
673  template<class TypeToFindx>
674  struct HasTypeInTypeList<meta::ListEnd,TypeToFindx> : meta::FalseCase{
675  };
676 
678  template<class TL,class TSL,size_t SIZE,class NOT_FOUND>
679  struct FindSizedType;
681  template<class TLH,class TLT,class TSLH,class TSLT,size_t SIZE,class NOT_FOUND>
682  struct FindSizedType<meta::TypeList<TLH,TLT>,meta::TypeList<TSLH,TSLT>,SIZE,NOT_FOUND>{
683  typedef typename FindSizedType<TLT,TSLT,SIZE,NOT_FOUND >::type type;
684  };
686  template<class TLH ,class TLT,class TSLT,size_t SIZE,class NOT_FOUND>
687  struct FindSizedType< meta::TypeList<TLH,TLT>,meta::TypeList< meta::SizeT<SIZE> ,TSLT>,SIZE,NOT_FOUND >{
688  typedef TLH type;
689  };
691  template<size_t SIZE,class NOT_FOUND>
692  struct FindSizedType< meta::ListEnd,meta::ListEnd,SIZE,NOT_FOUND >{
693  typedef NOT_FOUND type;
694  };
696  template<class TL,class OTHER_TL>
697  struct MergeTypeLists;
699  template<class THEAD,class TTAIL,class OTHER_TL>
700  struct MergeTypeLists<meta::TypeList<THEAD,TTAIL>,OTHER_TL>
701  {
702  typedef meta::TypeList<
703  THEAD,
704  typename MergeTypeLists<TTAIL,OTHER_TL>::type
705  > type;
706  };
708  template<class OTHER_TL>
709  struct MergeTypeLists<meta::ListEnd,OTHER_TL>
710  {
711  typedef OTHER_TL type;
712  };
713 
714 
715 
716 
717 
718  template<class TL, class RES_TL>
719  struct RemoveDuplicates;
720 
721 
722 
723  // entry poit
724  template<class TL>
725  struct RemoveDuplicates<TL, meta::ListEnd>{
726 
727 
728  // get the first type from tl
729  typedef typename TL::HeadType FirstEntry;
730  // rest of type list
731  typedef typename TL::TailType RestOfList;
732 
733  typedef typename RemoveDuplicates<
734  RestOfList,
735  meta::TypeList<FirstEntry, meta::ListEnd>
736  >::type type;
737  };
738 
739 
740 
741  template<class RES_TL>
742  struct RemoveDuplicates<meta::ListEnd, RES_TL>{
743  typedef RES_TL type;
744  };
745 
746  template<class TL, class RES_TL>
747  struct RemoveDuplicates{
748 
749  // get the first type from tl
750  typedef typename TL::HeadType FirstEntry;
751  // rest of type list
752  typedef typename TL::TailType RestOfList;
753 
754 
755  typedef typename meta::EvalIf<
756  meta::HasTypeInTypeList<RES_TL, FirstEntry>::value,
757  meta::Self<RES_TL>,
758  meta::BackInsert<RES_TL, FirstEntry>
759  >::type ResultTypeList;
760 
761  typedef typename RemoveDuplicates<
762  RestOfList,
763  ResultTypeList
764  >::type type;
765  };
766 
767 
768 
769  template<class TL,class OTHER_TL>
770  struct MergeTypeListsNoDuplicates{
771  typedef typename MergeTypeLists<TL, OTHER_TL>::type WithDuplicates;
772  typedef typename RemoveDuplicates<WithDuplicates, ListEnd>::type type;
773  };
774 
775 
776 
781  template<class TL,class TYPE>
782  struct InsertInTypeListOrMoveToEnd{
783  typedef typename meta::If<
784  meta::HasTypeInTypeList<
785  TL,
786  TYPE
787  >::value,
788  typename meta::BackInsert<
789  typename DeleteTypeInTypeList< TL,TYPE >::type,
790  TYPE
791  >::type,
792  typename meta::BackInsert<
793  TL,
794  TYPE
795  >::type
796  >::type type;
797  };
799  template<class TL, class OTHER_TL>
800  struct MergeTypeListsWithoutDups;
802  template<class TL, class THEAD, class TTAIL>
803  struct MergeTypeListsWithoutDups<TL, meta::TypeList<THEAD, TTAIL> > {
804  typedef typename MergeTypeListsWithoutDups<
805  typename meta::InsertInTypeListOrMoveToEnd<TL, THEAD>::type,
806  TTAIL
807  >::type type;
808  };
810  template<class TL>
811  struct MergeTypeListsWithoutDups<TL, meta::ListEnd> {
812  typedef TL type;
813  };
815  template<class TL>
816  struct HasDuplicatesInTypeList;
818  template<class THEAD,class TTAIL>
819  struct HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >{
820  typedef typename meta::EvalIf<
821  HasTypeInTypeList<TTAIL,THEAD>::value,
822  meta::Bool<true>,
823  HasDuplicatesInTypeList< TTAIL>
824  >::type type;
825 
826  enum Value{
827  value= HasDuplicatesInTypeList<meta::TypeList<THEAD,TTAIL> >::type::value
828  };
829  };
831  template< >
832  struct HasDuplicatesInTypeList<meta::ListEnd> : meta::FalseCase{
833  };
835  template<class MAYBE_TYPELIST,class EXPLICIT_FUNCTION_TYPE,bool EDITABLE>
836  struct GenerateFunctionTypeList{
837  typedef typename meta::TypeListFromMaybeTypeList<MAYBE_TYPELIST>::type StartTypeList;
838  typedef typename meta::If<
839  EDITABLE,
840  typename InsertInTypeListOrMoveToEnd<StartTypeList,EXPLICIT_FUNCTION_TYPE>::type,
841  StartTypeList
842  >::type type;
843 
844  };
846  template<class T>
847  struct CallTraits {
848  typedef T ValueType;
849  typedef T value_type;
850  typedef typename opengm::meta::AddReference<T>::type reference;
851  typedef typename opengm::meta::AddConstReference<T>::type const_reference;
852  typedef typename opengm::meta::If <
853  opengm::meta::TypeInfo<T>::IsFundamental::value,
854  typename opengm::meta::RemoveConst<T>::type const,
855  typename opengm::meta::AddConstReference<T>::type
856  >::type
857  param_type;
858  };
860  template<class TList ,template <class> class InstanceUnitType,class TListSrc>
861  class FieldHelper;
862  template<class ListHead,class ListTail,template <class> class InstanceUnitType,class TListSrc>
863  class FieldHelper< opengm::meta::TypeList<ListHead,ListTail> ,InstanceUnitType,TListSrc>
864  : public FieldHelper<ListHead,InstanceUnitType,TListSrc>,
865  public FieldHelper<ListTail,InstanceUnitType,TListSrc>{
866  };
867  template< class ListTail ,template <class> class InstanceUnitType,class TListSrc>
868  class FieldHelper
869  : public InstanceUnitType<ListTail>{
870  };
871  template< template <class> class InstanceUnitType,class TListSrc>
872  class FieldHelper<opengm::meta::ListEnd,InstanceUnitType,TListSrc>{
873  };
875  template<class TList ,template <class> class InstanceUnitType>
876  class Field
877  : public FieldHelper<TList,InstanceUnitType,TList>{
878  public:
879  public:
880  template <typename T>
881  struct RebingByType{
882  typedef InstanceUnitType<T> type;
883  };
884  template <size_t Index>
885  struct RebingByIndex{
886  typedef InstanceUnitType<typename TypeAtTypeList<TList,Index>::type > type;
887  };
888  };
890  template<class TList ,class TYPE2,template <class ,class > class InstanceUnitType,class TListSrc>
891  class Field2Helper;
893  template<class ListHead,class ListTail,class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
894  class Field2Helper< opengm::meta::TypeList<ListHead,ListTail> ,TYPE2,InstanceUnitType,TListSrc>
895  : public Field2Helper<ListHead,TYPE2,InstanceUnitType,TListSrc>,
896  public Field2Helper<ListTail,TYPE2,InstanceUnitType,TListSrc>{
897  };
899  template< class ListTail ,class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
900  class Field2Helper
901  : public InstanceUnitType<ListTail,TYPE2>{
902  };
904  template< class TYPE2,template <class,class> class InstanceUnitType,class TListSrc>
905  class Field2Helper<opengm::meta::ListEnd,TYPE2,InstanceUnitType,TListSrc>{
906  };
908  template<class TList,class TYPE2 ,template <class,class> class InstanceUnitType>
909  class Field2
910  :
911  public Field2Helper<TList,TYPE2,InstanceUnitType,TList>{
912  public:
913  public:
914  template <typename T>
915  struct RebingByType{
916  typedef InstanceUnitType<T,TYPE2> type;
917  };
918  template <size_t Index>
919  struct RebingByIndex{
920  typedef InstanceUnitType<typename TypeAtTypeList<TList,Index>::type,TYPE2 > type;
921  };
922  };
924  struct FieldAccess{
925  template<size_t Index,class IG>
926  static inline typename IG::template RebingByIndex<Index>::type &
927  byIndex
928  (
929  IG & instanceGenerator
930  ) {
931  return instanceGenerator;
932  }
933 
934  template<size_t Index,class IG>
935  static inline const typename IG::template RebingByIndex<Index>::type &
936  byIndex
937  (
938  const IG & instanceGenerator
939  ) {
940  return instanceGenerator;
941  }
942 
943  template<class T,class IG>
944  static inline typename IG::template RebingByType<T>::type &
945  byType
946  (
947  IG & instanceGenerator
948  ) {
949  return instanceGenerator;
950  }
951 
952  template<class T,class IG>
953  static inline const typename IG::template RebingByType<T>::type &
954  byType
955  (
956  const IG & instanceGenerator
957  ) {
958  return instanceGenerator;
959  }
960  };
962  template<class Factor,size_t FunctionIndex>
963  class GetFunctionFromFactor
964  {
965  typedef typename Factor::FunctionTypeList FunctionTypeList;
966  public:
967  typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
968  static inline const FunctionType & get(const Factor & factor) {
969  return factor. template function<FunctionIndex>();
970  }
971  static inline FunctionType & get( Factor & factor) {
972  return factor. template function<FunctionIndex>();
973  }
974  };
976  template<class Factor,size_t FunctionIndex>
977  class GetFunction;
979  template<class T,size_t FunctionIndex>
980  class GetFunction<opengm::Factor<T>,FunctionIndex >{
981  typedef typename Factor<T>::FunctionTypeList FunctionTypeList;
982  public:
983  typedef typename meta::TypeAtTypeList<FunctionTypeList,FunctionIndex>::type FunctionType;
984 
985  static inline const FunctionType & get(const Factor<T> & factor) {
986  return factor. template function<FunctionIndex>();
987  };
988  static inline FunctionType & get(Factor<T> & factor) {
989  return factor. template function<FunctionIndex>();
990  };
991  };
993  template<class T,class I,class L,size_t FunctionIndex>
994  class GetFunction<IndependentFactor<T,I,L>,FunctionIndex >{
995  public:
996  typedef typename IndependentFactor<T,I,L>::FunctionType FunctionType;
997  static inline const FunctionType & get(const IndependentFactor<T,I,L> & factor) {
998  return factor.template function<0>();
999  };
1000  static inline FunctionType & get(IndependentFactor<T,I,L> & factor) {
1001  return factor.template function<0>();
1002  };
1003  };
1005  template<class Factor>
1006  class GetFunctionTypeIndex;
1008  template<class T>
1009  class GetFunctionTypeIndex<opengm::Factor<T> >{
1010  public:
1011  static inline size_t get(const opengm::Factor<T> & factor) {
1012  return factor.functionType();
1013  }
1014  static inline size_t get(opengm::Factor<T> & factor) {
1015  return factor.functionType();
1016  }
1017  };
1019  template<class T,class I,class L>
1020  class GetFunctionTypeIndex<opengm::IndependentFactor<T,I,L> >{
1021  public:
1022  static inline size_t get(const opengm::IndependentFactor<T,I,L> & factor) {
1023  return 0;
1024  }
1025  static inline size_t get( opengm::IndependentFactor<T,I,L> & factor) {
1026  return 0;
1027  }
1028  };
1030  template <class T>
1031  class IsField : opengm::meta::FalseCase{};
1033  template<class TList ,template <class> class InstanceUnitType>
1034  class IsField< meta::Field<TList,InstanceUnitType> > : opengm::meta::TrueCase{};
1036  struct ErrorMessage{
1037  struct WRONG_FUNCTION_TYPE;
1038  };
1040  template <class MSG>
1041  struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_;
1042  template < >
1043  struct OPENGM_METAPROGRAMMING_COMPILE_TIME_ASSERTION_FAILED_<meta::EmptyType >{
1044  };
1046  template<bool>
1047  class Assert;
1048  template<>
1049  class Assert<true>{
1050  };
1052  template<class TLIST,size_t INITIAL_VALUE, template <size_t, size_t> class ACCUMULATOR>
1053  class Accumulate;
1055  template<class TLIST_HEAD,class TLIST_TAIL,size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
1056  class Accumulate<meta::TypeList<TLIST_HEAD,TLIST_TAIL>,INITIAL_VALUE ,ACCUMULATOR >{
1057  enum Value{
1058  value=Accumulate<
1059  TLIST_TAIL,
1060  ACCUMULATOR <
1061  INITIAL_VALUE,
1062  TLIST_HEAD::value
1063  >::value ,
1064  ACCUMULATOR
1065  >::value
1066  };
1067  typedef SizeT<
1068  Accumulate<
1069  TLIST_TAIL ,
1070  ACCUMULATOR<
1071  INITIAL_VALUE,
1072  TLIST_HEAD::value
1073  >::value ,
1074  ACCUMULATOR
1075  >::value
1076  > type;
1077  };
1079  template<size_t INITIAL_VALUE,template <size_t, size_t> class ACCUMULATOR>
1080  class Accumulate<meta::ListEnd,INITIAL_VALUE ,ACCUMULATOR >{
1081  enum Value{
1082  value=INITIAL_VALUE
1083  };
1084  typedef SizeT<INITIAL_VALUE> type;
1085  };
1086 
1087  template<class T>
1088  struct PromoteToFloatingPoint{
1089  typedef typename meta::If<
1090  meta::IsFloatingPoint<T>::value ,
1091  T,
1092  float
1093  >::type type;
1094  };
1095 
1096  // metaprogramming check if BASE is base class of DERIVED
1097  template <class BASE, class DERIVED>
1098  struct IsBaseOf {
1099  typedef char yes[1];
1100  typedef char no[2];
1101 
1102  static yes& test(BASE*);
1103  static no& test(...);
1104 
1105  static DERIVED* get(void);
1106 
1107  enum Value{
1108  value = (sizeof(test(get())) == sizeof(yes))
1109  };
1110  };
1111 
1112  // metaprogramming check if T is a valid trait
1113  template <class T>
1114  struct IsValidTrait {
1115  static const bool value = !Compare<typename T::ValueType, LinearConstraintFunctionTraitsUndefined>::value;
1116  };
1117  // constraint function typelist
1118  // metaprogramming get linear constraint function typelist
1119  // note: LinearConstraintFunctionTypeList might return an empty type list containing only meta::ListEnd elements.
1120  // This happens if TL does not contain any linear constraint function
1121  template <class TL>
1122  struct GetLinearConstraintFunctionTypeList;
1123 
1124  // metaprogramming get linear constraint function typelist
1125  template<class THEAD,class TTAIL>
1126  struct GetLinearConstraintFunctionTypeList<TypeList<THEAD,TTAIL> > {
1127  typedef TypeList<THEAD, typename GetLinearConstraintFunctionTypeList<TTAIL>::type > true_type;
1128  typedef typename TypeListFromMaybeTypeList<typename GetLinearConstraintFunctionTypeList<TTAIL>::type>::type false_type;
1129 
1130  template <class FUNCTION, bool IS_COMPLETE_TYPE>
1131  struct IsLinearConstraintFunction {
1132  typedef false_type type;
1133  };
1134 
1135  template <class FUNCTION>
1136  struct IsLinearConstraintFunction<FUNCTION, true> {
1137  typedef typename If<IsBaseOf<opengm::LinearConstraintFunctionBase<FUNCTION>, FUNCTION>::value, true_type, false_type>::type type;
1138  };
1139  typedef IsValidTrait<opengm::LinearConstraintFunctionTraits<THEAD> > IsCompleteLinearConstraintFunction;
1140  // add THEAD only if it is derived from LinearConstraintBase<THEAD>
1141  typedef typename IsLinearConstraintFunction<THEAD, IsCompleteLinearConstraintFunction::value>::type type;
1142  };
1143 
1144  // metaprogramming get linear constraint function typelist
1145  template<>
1146  struct GetLinearConstraintFunctionTypeList<ListEnd> {
1147  typedef ListEnd type;
1148  };
1149  } // namespace meta
1150 
1151 
1161  template
1162  <
1163  class T1,
1164  class T2 = meta::ListEnd,
1165  class T3 = meta::ListEnd,
1166  class T4 = meta::ListEnd,
1167  class T5 = meta::ListEnd,
1168  class T6 = meta::ListEnd,
1169  class T7 = meta::ListEnd,
1170  class T8 = meta::ListEnd,
1171  class T9 = meta::ListEnd,
1172  class T10 = meta::ListEnd,
1173  class T11 = meta::ListEnd,
1174  class T12 = meta::ListEnd,
1175  class T13 = meta::ListEnd,
1176  class T14 = meta::ListEnd,
1177  class T15 = meta::ListEnd
1178  >
1179  struct FunctionTypeListGenerator {
1180  typedef meta::TypeList<T1, typename FunctionTypeListGenerator<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::type > type;
1181  };
1182 
1183  template< >
1184  struct FunctionTypeListGenerator<meta::ListEnd> {
1185  typedef meta::ListEnd type;
1186  };
1187 
1189 
1190 } // namespace opengm
1191 
1192 #endif // #ifndef OPENGM_METAPROGRAMMING
1193 
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...
ExplicitFunction< ValueType, IndexType, LabelType > FunctionType