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