36 #ifndef VIGRA_METAPROGRAMMING_HXX 
   37 #define VIGRA_METAPROGRAMMING_HXX 
   48 #pragma warning( push ) 
   49 #pragma warning( disable : 4503 ) 
   53 #include <AssertMacros.h> 
   61     static const int value = N;
 
   64 template <
int N1, 
int N2>
 
   68     static const int value = N1 < N2 ? N2 : N1;
 
   71 template <
int N1, 
int N2>
 
   75     static const int value = N1 < N2 ? N1 : N2;
 
   80    static const bool asBool = 
true, value = 
true;
 
   85     static const bool asBool = 
false, value = 
false;
 
  142     typedef VigraFalseType isConst;
 
  143     typedef VigraFalseType isPOD;
 
  144     typedef VigraFalseType isBuiltinType;
 
  147 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 
  150 class TypeTraits<T const>
 
  151 : 
public TypeTraits<T>
 
  154     typedef VigraTrueType isConst;
 
  158 class TypeTraits<T *>
 
  161     typedef VigraFalseType isConst;
 
  162     typedef VigraTrueType isPOD;
 
  163     typedef VigraTrueType isBuiltinType;
 
  167 class TypeTraits<T const *>
 
  170     typedef VigraFalseType isConst;
 
  171     typedef VigraTrueType isPOD;
 
  172     typedef VigraTrueType isBuiltinType;
 
  175 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 
  184 #define VIGRA_TYPE_TRAITS(type, size) \ 
  186 class TypeTraits<type> \ 
  189     typedef VigraFalseType isConst; \ 
  190     typedef VigraTrueType isPOD; \ 
  191     typedef VigraTrueType isBuiltinType; \ 
  192     typedef char TypeToSize[size]; \ 
  196   TypeTraits<type>::TypeToSize * typeToSize(type); \ 
  199   struct SizeToType<size> \ 
  201       typedef type result; \ 
  205 VIGRA_TYPE_TRAITS(
char, 1)
 
  206 VIGRA_TYPE_TRAITS(
signed char, 2)
 
  207 VIGRA_TYPE_TRAITS(
unsigned char, 3)
 
  208 VIGRA_TYPE_TRAITS(
short, 4)
 
  209 VIGRA_TYPE_TRAITS(
unsigned short, 5)
 
  210 VIGRA_TYPE_TRAITS(
int, 6)
 
  211 VIGRA_TYPE_TRAITS(
unsigned int, 7)
 
  212 VIGRA_TYPE_TRAITS(
long, 8)
 
  213 VIGRA_TYPE_TRAITS(
unsigned long, 9)
 
  214 VIGRA_TYPE_TRAITS(
float, 10)
 
  215 VIGRA_TYPE_TRAITS(
double, 11)
 
  216 VIGRA_TYPE_TRAITS(
long double, 12)
 
  218 VIGRA_TYPE_TRAITS(
long long, 13)
 
  219 VIGRA_TYPE_TRAITS(
unsigned long long, 14)
 
  222 #undef VIGRA_TYPE_TRAITS 
  230 struct Not<VigraTrueType>
 
  232     typedef VigraFalseType result;        
 
  233     static const bool boolResult = 
false; 
 
  234     typedef VigraFalseType type;
 
  235     static const bool value = 
false;
 
  239 struct Not<VigraFalseType>
 
  241     typedef VigraTrueType result;        
 
  242     static const bool boolResult = 
true; 
 
  243     typedef VigraTrueType type;
 
  244     static const bool value = 
true;
 
  247 template <
class L, 
class R>
 
  251 struct And<VigraFalseType, VigraFalseType>
 
  253     typedef VigraFalseType result;        
 
  254     static const bool boolResult = 
false; 
 
  255     typedef VigraFalseType type;
 
  256     static const bool value = 
false;
 
  260 struct And<VigraFalseType, VigraTrueType>
 
  262     typedef VigraFalseType result;        
 
  263     static const bool boolResult = 
false; 
 
  264     typedef VigraFalseType type;
 
  265     static const bool value = 
false;
 
  269 struct And<VigraTrueType, VigraFalseType>
 
  271     typedef VigraFalseType result;        
 
  272     static const bool boolResult = 
false; 
 
  273     typedef VigraFalseType type;
 
  274     static const bool value = 
false;
 
  278 struct And<VigraTrueType, VigraTrueType>
 
  280     typedef VigraTrueType result;        
 
  281     static const bool boolResult = 
true; 
 
  282     typedef VigraTrueType type;
 
  283     static const bool value = 
true;
 
  286 template <
class L, 
class R>
 
  290 struct Or<VigraFalseType, VigraFalseType>
 
  292     typedef VigraFalseType result;        
 
  293     static const bool boolResult = 
false; 
 
  294     typedef VigraFalseType type;
 
  295     static const bool value = 
false;
 
  299 struct Or<VigraTrueType, VigraFalseType>
 
  301     typedef VigraTrueType result;        
 
  302     static const bool boolResult = 
true; 
 
  303     typedef VigraTrueType type;
 
  304     static const bool value = 
true;
 
  308 struct Or<VigraFalseType, VigraTrueType>
 
  310     typedef VigraTrueType result;        
 
  311     static const bool boolResult = 
true; 
 
  312     typedef VigraTrueType type;
 
  313     static const bool value = 
true;
 
  317 struct Or<VigraTrueType, VigraTrueType>
 
  319     typedef VigraTrueType result;        
 
  320     static const bool boolResult = 
true; 
 
  321     typedef VigraTrueType type;
 
  322     static const bool value = 
true;
 
  325 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 
  327 template <
class PREDICATE, 
class TRUECASE, 
class FALSECASE>
 
  330 template <
class TRUECASE, 
class FALSECASE>
 
  331 struct If<VigraTrueType, TRUECASE, FALSECASE>
 
  333     typedef TRUECASE type;
 
  336 template <
class TRUECASE, 
class FALSECASE>
 
  337 struct If<VigraFalseType, TRUECASE, FALSECASE>
 
  339     typedef FALSECASE type;
 
  342 template <
bool PREDICATE, 
class TRUECASE, 
class FALSECASE>
 
  345 template <
class TRUECASE, 
class FALSECASE>
 
  346 struct IfBool<true, TRUECASE, FALSECASE>
 
  348     typedef TRUECASE type;
 
  351 template <
class TRUECASE, 
class FALSECASE>
 
  352 struct IfBool<false, TRUECASE, FALSECASE>
 
  354     typedef FALSECASE type;
 
  357 template <
class L, 
class R>
 
  360     typedef VigraFalseType result;        
 
  361     static const bool boolResult = 
false; 
 
  362     typedef VigraFalseType type;
 
  363     static const bool value = 
false;
 
  367 struct IsSameType<T, T>
 
  369     typedef VigraTrueType result;        
 
  370     static const bool boolResult = 
true; 
 
  371     typedef VigraTrueType type;
 
  372     static const bool value = 
true;
 
  375 template <
class L, 
class R>
 
  376 struct IsDifferentType
 
  378     typedef VigraTrueType type;
 
  379     static const bool value = 
true;
 
  383 struct IsDifferentType<T, T>
 
  385     typedef VigraFalseType type;
 
  386     static const bool value = 
false;
 
  389 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 
  391 template <
class From, 
class To>
 
  392 struct IsConvertibleTo
 
  394     typedef char falseResult[1];
 
  395     typedef char trueResult[2];
 
  397     static From 
const & check();
 
  399     static falseResult * testIsConvertible(...);
 
  400     static trueResult * testIsConvertible(To 
const &);
 
  402     enum { resultSize = 
sizeof(*testIsConvertible(check())) };
 
  404     static const bool value = (resultSize == 2);
 
  406         IfBool<value, VigraTrueType, VigraFalseType>::type
 
  410 template <
class DERIVED, 
class BASE>
 
  413     typedef char falseResult[1];
 
  414     typedef char trueResult[2];
 
  416     static falseResult * testIsDerivedFrom(...);
 
  417     static trueResult * testIsDerivedFrom(BASE 
const *);
 
  419     enum { resultSize = 
sizeof(*testIsDerivedFrom(static_cast<DERIVED const *>(0))) };
 
  421     static const bool value = (resultSize == 2);
 
  423         IfBool<value, VigraTrueType, VigraFalseType>::type
 
  426     static const bool boolResult = value; 
 
  431 struct UnqualifiedType
 
  434     static const bool isConst = 
false;
 
  435     static const bool isReference = 
false;
 
  436     static const bool isPointer = 
false;
 
  440 struct UnqualifiedType<T const>
 
  443     static const bool isConst = 
true;
 
  444     static const bool isReference = 
false;
 
  445     static const bool isPointer = 
false;
 
  449 struct UnqualifiedType<T &>
 
  450 : 
public UnqualifiedType<T>
 
  452     static const bool isReference = 
true;
 
  456 struct UnqualifiedType<T const &>
 
  457 : 
public UnqualifiedType<T const>
 
  459     static const bool isReference = 
true;
 
  463 struct UnqualifiedType<T *>
 
  464 : 
public UnqualifiedType<T>
 
  466     static const bool isPointer = 
true;
 
  470 struct UnqualifiedType<T const *>
 
  471 : 
public UnqualifiedType<T const>
 
  473     static const bool isPointer = 
true;
 
  476 template <
bool, 
class T = 
void>
 
  479 struct enable_if<true, T> { 
typedef T type; };
 
  483 template <
class T, 
template<
class> 
class USER>
 
  486     typedef char falseResult[1];
 
  487     typedef char trueResult[2];
 
  489     static falseResult * test(...);
 
  490     static trueResult * test(USER<sfinae_void>);
 
  492     enum { resultSize = 
sizeof(*test(static_cast<T*>(0))) };
 
  494     static const bool value = (resultSize == 2);
 
  496         IfBool<value, VigraTrueType, VigraFalseType>::type
 
  501 struct has_argument_type : 
public sfinae_test<T, has_argument_type>
 
  503     template <
class U> has_argument_type(U*, 
typename U::argument_type* = 0);
 
  507 struct has_result_type : 
public sfinae_test<T, has_result_type>
 
  509     template <
class U> has_result_type(U*, 
typename U::result_type* = 0);
 
  513 struct has_value_type : 
public sfinae_test<T, has_value_type>
 
  515     template <
class U> has_value_type(U*, 
typename U::value_type* = 0);
 
  519 struct IsIterator : 
public sfinae_test<T, IsIterator>
 
  521     template <
class U> IsIterator(U*, 
typename U::iterator_category* = 0);
 
  525 struct IsIterator<T*>
 
  527     static const bool value = 
true;
 
  528     typedef VigraTrueType type;
 
  532 struct IsIterator<T const *>
 
  534     static const bool value = 
true;
 
  535     typedef VigraTrueType type;
 
  539 struct has_real_promote_type : 
public sfinae_test<T, has_real_promote_type>
 
  542     has_real_promote_type(U*, 
typename U::real_promote_type* = 0);
 
  545 template <class T, bool P = has_real_promote_type<T>::value>
 
  546 struct get_optional_real_promote
 
  551 struct get_optional_real_promote<T, true>
 
  553     typedef typename T::real_promote_type type;
 
  559     typedef char falseResult[1];
 
  560     typedef char trueResult[2];
 
  562     static falseResult * test(...);
 
  563     template <
class U, 
unsigned n>
 
  564     static trueResult * test(U (*)[n]);
 
  566     enum { resultSize = 
sizeof(*test(static_cast<T*>(0))) };
 
  568     static const bool value = (resultSize == 2);
 
  570         IfBool<value, VigraTrueType, VigraFalseType>::type
 
  575 template <
class D, 
class B, 
class Z> 
inline 
  576 D & static_cast_2(Z & z)
 
  578     return static_cast<D &
>(
static_cast<B &
>(z));
 
  582 class copy_if_same_as
 
  586     copy_if_same_as(
const copy_if_same_as &);
 
  587     void operator=(
const copy_if_same_as &);
 
  589     copy_if_same_as(
const A & x, 
const A & y)
 
  590         : copied(&x == &y), data(copied ? new A(y) : &x) {}
 
  596     const A & operator()()
 const { 
return *data; }
 
  601 struct true_test : 
public VigraTrueType {};
 
  604 struct false_test : VigraFalseType {};
 
  606 template <
class PC, 
class T, 
class F>
 
  609     static const bool value = IfBool<PC::value, T, F>::type::value;
 
  615     template <
class A, 
class B>
 
  616     static const A & at(
const A & a, 
const B &) { 
return a; }
 
  617     template <
class A, 
class B>
 
  618     static       A & at(      A & a,       B &) { 
return a; }
 
  621 struct choose_type<false>
 
  623     template <
class A, 
class B>
 
  624     static const B & at(
const A &, 
const B & b) { 
return b; }
 
  625     template <
class A, 
class B>
 
  626     static       B & at(      A &,       B & b) { 
return b; }
 
  632     static const bool value =   !std::numeric_limits<X>::is_signed
 
  633                               && std::numeric_limits<X>::is_integer;
 
  636 struct EnableMetaLog2
 
  637     : 
public enable_if<HasMetaLog2<X>::value> {};
 
  639 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
 
  642 template <
class X = 
unsigned long,
 
  643           X n = ~(X(0)), 
unsigned s = 1, 
unsigned t = 0, 
bool q = 1,
 
  644           X m = 0, X z = 0, X u = 1, 
class = 
void>
 
  646     : 
public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
 
  648 template <
class X, X n, 
unsigned s, 
unsigned t, 
bool q, X m, X z, X u>
 
  649 struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
 
  651     static const unsigned value
 
  652         = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
 
  654 template <
class X, 
unsigned s, 
unsigned t, 
bool q, X m, X z, X u>
 
  655 struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
 
  657     static const unsigned value
 
  658         = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
 
  660 template <
class X, 
unsigned s, 
unsigned t, 
bool q, X z, X u>
 
  661 struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
 
  663     static const unsigned value = 2;
 
  665 template <
class X, 
unsigned s, 
unsigned t, 
bool q, X z, X u>
 
  666 struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
 
  668     static const unsigned value = 1;
 
  670 template <
class X, X z, X u>
 
  671 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
 
  675     static const unsigned value = 0;
 
  678 template <
int X, 
unsigned int N>
 
  681     static const long long value = MetaPow<X, N-1>::value * X;
 
  687     static const long long value = 1;
 
  696 template<
class HEAD, 
class TAIL=
void>
 
  699     typedef TypeList<HEAD, TAIL> type;
 
  704 template <
class List, 
class T>
 
  707 template <
class Head, 
class Tail, 
class T>
 
  708 struct Contains<TypeList<Head, Tail>, T>
 
  710     typedef typename Contains<Tail, T>::type type;
 
  713 template <
class Head, 
class Tail>
 
  714 struct Contains<TypeList<Head, Tail>, Head>
 
  716     typedef VigraTrueType type;
 
  720 struct Contains<void, T>
 
  722     typedef VigraFalseType type;
 
  725 template <
class List, 
class T>
 
  728 template <
class Head, 
class Tail, 
class T>
 
  729 struct Remove<TypeList<Head, Tail>, T>
 
  731     typedef TypeList<Head, typename Remove<Tail, T>::type> type;
 
  734 template <
class Head, 
class Tail>
 
  735 struct Remove<TypeList<Head, Tail>, Head>
 
  741 struct Remove<void, T>
 
  746 template <
class A, 
class Tail=
void>
 
  749     typedef TypeList<A, typename Tail::type> type;
 
  752 template <
class Head, 
class Tail, 
class List>
 
  753 struct Push<TypeList<Head, Tail>, List>
 
  755     typedef typename Push<Tail, List>::type Rest;
 
  756     typedef TypeList<Head, Rest> type;
 
  759 template <
class Head, 
class Tail>
 
  760 struct Push<TypeList<Head, Tail>, void>
 
  762     typedef TypeList<Head, Tail> type;
 
  768     typedef TypeList<A> type;
 
  778 struct Push<void, void>
 
  783 template <
class A, 
class Tail=
void>
 
  786     typedef typename Contains<Tail, A>::type AlreadyInList;
 
  787     typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
 
  790 template <
class Head, 
class Tail, 
class List>
 
  791 struct PushUnique<TypeList<Head, Tail>, List>
 
  793     typedef typename PushUnique<Tail, List>::type Rest;
 
  794     typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
 
  795     typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
 
  798 template <
class Head, 
class Tail>
 
  799 struct PushUnique<TypeList<Head, Tail>, void>
 
  801     typedef TypeList<Head, Tail> type;
 
  805 struct PushUnique<A, void>
 
  807     typedef TypeList<A> type;
 
  811 struct PushUnique<void, A>
 
  817 struct PushUnique<void, void>
 
  822 template <
class T01=void, 
class T02=void, 
class T03=void, 
class T04=void, 
class T05=void,
 
  823           class T06=void, 
class T07=void, 
class T08=void, 
class T09=void, 
class T10=void,
 
  824           class T11=void, 
class T12=void, 
class T13=void, 
class T14=void, 
class T15=void,
 
  825           class T16=void, 
class T17=void, 
class T18=void, 
class T19=void, 
class T20=
void>
 
  828     typedef typename Push<T19, T20>::type L19;
 
  829     typedef typename Push<T18, L19>::type L18;
 
  830     typedef typename Push<T17, L18>::type L17;
 
  831     typedef typename Push<T16, L17>::type L16;
 
  832     typedef typename Push<T15, L16>::type L15;
 
  833     typedef typename Push<T14, L15>::type L14;
 
  834     typedef typename Push<T13, L14>::type L13;
 
  835     typedef typename Push<T12, L13>::type L12;
 
  836     typedef typename Push<T11, L12>::type L11;
 
  837     typedef typename Push<T10, L11>::type L10;
 
  838     typedef typename Push<T09, L10>::type L09;
 
  839     typedef typename Push<T08, L09>::type L08;
 
  840     typedef typename Push<T07, L08>::type L07;
 
  841     typedef typename Push<T06, L07>::type L06;
 
  842     typedef typename Push<T05, L06>::type L05;
 
  843     typedef typename Push<T04, L05>::type L04;
 
  844     typedef typename Push<T03, L04>::type L03;
 
  845     typedef typename Push<T02, L03>::type L02;
 
  846     typedef typename Push<T01, L02>::type L01;
 
  850 template <
class T01=void, 
class T02=void, 
class T03=void, 
class T04=void, 
class T05=void,
 
  851           class T06=void, 
class T07=void, 
class T08=void, 
class T09=void, 
class T10=void,
 
  852           class T11=void, 
class T12=void, 
class T13=void, 
class T14=void, 
class T15=void,
 
  853           class T16=void, 
class T17=void, 
class T18=void, 
class T19=void, 
class T20=
void>
 
  854 struct MakeTypeListUnique
 
  856     typedef typename PushUnique<T19, T20>::type L19;
 
  857     typedef typename PushUnique<T18, L19>::type L18;
 
  858     typedef typename PushUnique<T17, L18>::type L17;
 
  859     typedef typename PushUnique<T16, L17>::type L16;
 
  860     typedef typename PushUnique<T15, L16>::type L15;
 
  861     typedef typename PushUnique<T14, L15>::type L14;
 
  862     typedef typename PushUnique<T13, L14>::type L13;
 
  863     typedef typename PushUnique<T12, L13>::type L12;
 
  864     typedef typename PushUnique<T11, L12>::type L11;
 
  865     typedef typename PushUnique<T10, L11>::type L10;
 
  866     typedef typename PushUnique<T09, L10>::type L09;
 
  867     typedef typename PushUnique<T08, L09>::type L08;
 
  868     typedef typename PushUnique<T07, L08>::type L07;
 
  869     typedef typename PushUnique<T06, L07>::type L06;
 
  870     typedef typename PushUnique<T05, L06>::type L05;
 
  871     typedef typename PushUnique<T04, L05>::type L04;
 
  872     typedef typename PushUnique<T03, L04>::type L03;
 
  873     typedef typename PushUnique<T02, L03>::type L02;
 
  874     typedef typename PushUnique<T01, L02>::type L01;
 
  878 template <
typename T0>
 
  879 inline void ignore_argument(
const T0 &)
 
  882 template <
typename T0, 
typename T1>
 
  883 inline void ignore_argument(
const T0 &, 
const T1 &)
 
  886 template <
typename T0, 
typename T1, 
typename T2>
 
  887 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &)
 
  890 template <
typename T0, 
typename T1, 
typename T2, 
typename T3>
 
  891 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &)
 
  894 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4>
 
  895 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &)
 
  898 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4, 
typename T5>
 
  899 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &, 
const T5 &)
 
  902 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4, 
typename T5, 
typename T6>
 
  903 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &, 
const T5 &, 
const T6 &)
 
  906 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4, 
typename T5, 
typename T6, 
typename T7>
 
  907 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &, 
const T5 &, 
const T6 &, 
const T7 &)
 
  910 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4, 
typename T5, 
typename T6, 
typename T7, 
typename T8>
 
  911 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &, 
const T5 &, 
const T6 &, 
const T7 &, 
const T8 &)
 
  914 template <
typename T0, 
typename T1, 
typename T2, 
typename T3, 
typename T4, 
typename T5, 
typename T6, 
typename T7, 
typename T8, 
typename T9>
 
  915 inline void ignore_argument(
const T0 &, 
const T1 &, 
const T2 &, 
const T3 &, 
const T4 &, 
const T5 &, 
const T6 &, 
const T7 &, 
const T8 &, 
const T9 &)
 
  919 #if defined(_MSC_VER) 
  920 #pragma warning( pop ) 
Definition: metaprogramming.hxx:116
Definition: metaprogramming.hxx:123
Definition: metaprogramming.hxx:130