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;
64template <
int N1,
int N2>
68 static const int value = N1 < N2 ? N2 : N1;
71template <
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
150class TypeTraits<T const>
151:
public TypeTraits<T>
154 typedef VigraTrueType isConst;
161 typedef VigraFalseType isConst;
162 typedef VigraTrueType isPOD;
163 typedef VigraTrueType isBuiltinType;
167class TypeTraits<T const *>
170 typedef VigraFalseType isConst;
171 typedef VigraTrueType isPOD;
172 typedef VigraTrueType isBuiltinType;
184#define VIGRA_TYPE_TRAITS(type, size) \
186class 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; \
205VIGRA_TYPE_TRAITS(
char, 1)
206VIGRA_TYPE_TRAITS(
signed char, 2)
207VIGRA_TYPE_TRAITS(
unsigned char, 3)
208VIGRA_TYPE_TRAITS(
short, 4)
209VIGRA_TYPE_TRAITS(
unsigned short, 5)
210VIGRA_TYPE_TRAITS(
int, 6)
211VIGRA_TYPE_TRAITS(
unsigned int, 7)
212VIGRA_TYPE_TRAITS(
long, 8)
213VIGRA_TYPE_TRAITS(
unsigned long, 9)
214VIGRA_TYPE_TRAITS(
float, 10)
215VIGRA_TYPE_TRAITS(
double, 11)
216VIGRA_TYPE_TRAITS(
long double, 12)
218VIGRA_TYPE_TRAITS(
long long, 13)
219VIGRA_TYPE_TRAITS(
unsigned long long, 14)
222#undef VIGRA_TYPE_TRAITS
230struct Not<VigraTrueType>
232 typedef VigraFalseType result;
233 static const bool boolResult =
false;
234 typedef VigraFalseType type;
235 static const bool value =
false;
239struct Not<VigraFalseType>
241 typedef VigraTrueType result;
242 static const bool boolResult =
true;
243 typedef VigraTrueType type;
244 static const bool value =
true;
247template <
class L,
class R>
251struct And<VigraFalseType, VigraFalseType>
253 typedef VigraFalseType result;
254 static const bool boolResult =
false;
255 typedef VigraFalseType type;
256 static const bool value =
false;
260struct And<VigraFalseType, VigraTrueType>
262 typedef VigraFalseType result;
263 static const bool boolResult =
false;
264 typedef VigraFalseType type;
265 static const bool value =
false;
269struct And<VigraTrueType, VigraFalseType>
271 typedef VigraFalseType result;
272 static const bool boolResult =
false;
273 typedef VigraFalseType type;
274 static const bool value =
false;
278struct And<VigraTrueType, VigraTrueType>
280 typedef VigraTrueType result;
281 static const bool boolResult =
true;
282 typedef VigraTrueType type;
283 static const bool value =
true;
286template <
class L,
class R>
290struct Or<VigraFalseType, VigraFalseType>
292 typedef VigraFalseType result;
293 static const bool boolResult =
false;
294 typedef VigraFalseType type;
295 static const bool value =
false;
299struct Or<VigraTrueType, VigraFalseType>
301 typedef VigraTrueType result;
302 static const bool boolResult =
true;
303 typedef VigraTrueType type;
304 static const bool value =
true;
308struct Or<VigraFalseType, VigraTrueType>
310 typedef VigraTrueType result;
311 static const bool boolResult =
true;
312 typedef VigraTrueType type;
313 static const bool value =
true;
317struct 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
327template <
class PREDICATE,
class TRUECASE,
class FALSECASE>
330template <
class TRUECASE,
class FALSECASE>
331struct If<VigraTrueType, TRUECASE, FALSECASE>
333 typedef TRUECASE type;
336template <
class TRUECASE,
class FALSECASE>
337struct If<VigraFalseType, TRUECASE, FALSECASE>
339 typedef FALSECASE type;
342template <
bool PREDICATE,
class TRUECASE,
class FALSECASE>
345template <
class TRUECASE,
class FALSECASE>
346struct IfBool<true, TRUECASE, FALSECASE>
348 typedef TRUECASE type;
351template <
class TRUECASE,
class FALSECASE>
352struct IfBool<false, TRUECASE, FALSECASE>
354 typedef FALSECASE type;
357template <
class L,
class R>
360 typedef VigraFalseType result;
361 static const bool boolResult =
false;
362 typedef VigraFalseType type;
363 static const bool value =
false;
367struct IsSameType<T, T>
369 typedef VigraTrueType result;
370 static const bool boolResult =
true;
371 typedef VigraTrueType type;
372 static const bool value =
true;
375template <
class L,
class R>
376struct IsDifferentType
378 typedef VigraTrueType type;
379 static const bool value =
true;
383struct IsDifferentType<T, T>
385 typedef VigraFalseType type;
386 static const bool value =
false;
391template <
class From,
class To>
392struct 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
410template <
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;
431struct UnqualifiedType
434 static const bool isConst =
false;
435 static const bool isReference =
false;
436 static const bool isPointer =
false;
440struct UnqualifiedType<T const>
443 static const bool isConst =
true;
444 static const bool isReference =
false;
445 static const bool isPointer =
false;
449struct UnqualifiedType<T &>
450:
public UnqualifiedType<T>
452 static const bool isReference =
true;
456struct UnqualifiedType<T const &>
457:
public UnqualifiedType<T const>
459 static const bool isReference =
true;
463struct UnqualifiedType<T *>
464:
public UnqualifiedType<T>
466 static const bool isPointer =
true;
470struct UnqualifiedType<T const *>
471:
public UnqualifiedType<T const>
473 static const bool isPointer =
true;
476template <
bool,
class T =
void>
479struct enable_if<true, T> {
typedef T type; };
483template <
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
501struct has_argument_type :
public sfinae_test<T, has_argument_type>
503 template <
class U> has_argument_type(U*,
typename U::argument_type* = 0);
507struct has_result_type :
public sfinae_test<T, has_result_type>
509 template <
class U> has_result_type(U*,
typename U::result_type* = 0);
513struct has_value_type :
public sfinae_test<T, has_value_type>
515 template <
class U> has_value_type(U*,
typename U::value_type* = 0);
519struct IsIterator :
public sfinae_test<T, IsIterator>
521 template <
class U> IsIterator(U*,
typename U::iterator_category* = 0);
527 static const bool value =
true;
528 typedef VigraTrueType type;
532struct IsIterator<T const *>
534 static const bool value =
true;
535 typedef VigraTrueType type;
539struct has_real_promote_type :
public sfinae_test<T, has_real_promote_type>
542 has_real_promote_type(U*,
typename U::real_promote_type* = 0);
545template <class T, bool P = has_real_promote_type<T>::value>
546struct get_optional_real_promote
551struct 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
575template <
class D,
class B,
class Z>
inline
576D & static_cast_2(Z & z)
578 return static_cast<D &
>(
static_cast<B &
>(z));
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; }
601struct true_test :
public VigraTrueType {};
604struct false_test : VigraFalseType {};
606template <
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; }
621struct 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;
637 :
public enable_if<HasMetaLog2<X>::value> {};
639class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
642template <
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>
648template <
class X, X n,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
649struct 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;
654template <
class X,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
655struct 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;
660template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
661struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
663 static const unsigned value = 2;
665template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
666struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
668 static const unsigned value = 1;
670template <
class X, X z, X u>
671struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
675 static const unsigned value = 0;
678template <
int X,
unsigned int N>
681 static const long long value = MetaPow<X, N-1>::value * X;
687 static const long long value = 1;
696template<
class HEAD,
class TAIL=
void>
699 typedef TypeList<HEAD, TAIL> type;
704template <
class List,
class T>
707template <
class Head,
class Tail,
class T>
708struct Contains<TypeList<Head, Tail>, T>
710 typedef typename Contains<Tail, T>::type type;
713template <
class Head,
class Tail>
714struct Contains<TypeList<Head, Tail>, Head>
716 typedef VigraTrueType type;
720struct Contains<void, T>
722 typedef VigraFalseType type;
725template <
class List,
class T>
728template <
class Head,
class Tail,
class T>
729struct Remove<TypeList<Head, Tail>, T>
731 typedef TypeList<Head, typename Remove<Tail, T>::type> type;
734template <
class Head,
class Tail>
735struct Remove<TypeList<Head, Tail>, Head>
741struct Remove<void, T>
746template <
class A,
class Tail=
void>
749 typedef TypeList<A, typename Tail::type> type;
752template <
class Head,
class Tail,
class List>
753struct Push<TypeList<Head, Tail>, List>
755 typedef typename Push<Tail, List>::type Rest;
756 typedef TypeList<Head, Rest> type;
759template <
class Head,
class Tail>
760struct Push<TypeList<Head, Tail>, void>
762 typedef TypeList<Head, Tail> type;
768 typedef TypeList<A> type;
778struct Push<void, void>
783template <
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;
790template <
class Head,
class Tail,
class List>
791struct 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;
798template <
class Head,
class Tail>
799struct PushUnique<TypeList<Head, Tail>, void>
801 typedef TypeList<Head, Tail> type;
805struct PushUnique<A, void>
807 typedef TypeList<A> type;
811struct PushUnique<void, A>
817struct PushUnique<void, void>
822template <
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;
850template <
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>
854struct 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;
878template <
typename T0>
879inline void ignore_argument(
const T0 &)
882template <
typename T0,
typename T1>
883inline void ignore_argument(
const T0 &,
const T1 &)
886template <
typename T0,
typename T1,
typename T2>
887inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &)
890template <
typename T0,
typename T1,
typename T2,
typename T3>
891inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &)
894template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
895inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &)
898template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
899inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &,
const T5 &)
902template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
903inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &,
const T5 &,
const T6 &)
906template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
907inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &,
const T5 &,
const T6 &,
const T7 &)
910template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8>
911inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &,
const T5 &,
const T6 &,
const T7 &,
const T8 &)
914template <
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
915inline void ignore_argument(
const T0 &,
const T1 &,
const T2 &,
const T3 &,
const T4 &,
const T5 &,
const T6 &,
const T7 &,
const T8 &,
const T9 &)
920#pragma warning( pop )
Definition: metaprogramming.hxx:130
Definition: metaprogramming.hxx:116
Definition: metaprogramming.hxx:123