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;
131 typedef VigraFalseType isConst;
132 typedef VigraFalseType isPOD;
133 typedef VigraFalseType isBuiltinType;
136 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
139 class TypeTraits<T const>
140 :
public TypeTraits<T>
143 typedef VigraTrueType isConst;
147 class TypeTraits<T *>
150 typedef VigraFalseType isConst;
151 typedef VigraTrueType isPOD;
152 typedef VigraTrueType isBuiltinType;
156 class TypeTraits<T const *>
159 typedef VigraFalseType isConst;
160 typedef VigraTrueType isPOD;
161 typedef VigraTrueType isBuiltinType;
164 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
173 #define VIGRA_TYPE_TRAITS(type, size) \
175 class TypeTraits<type> \
178 typedef VigraFalseType isConst; \
179 typedef VigraTrueType isPOD; \
180 typedef VigraTrueType isBuiltinType; \
181 typedef char TypeToSize[size]; \
185 TypeTraits<type>::TypeToSize * typeToSize(type); \
188 struct SizeToType<size> \
190 typedef type result; \
194 VIGRA_TYPE_TRAITS(
char, 1)
195 VIGRA_TYPE_TRAITS(
signed char, 2)
196 VIGRA_TYPE_TRAITS(
unsigned char, 3)
197 VIGRA_TYPE_TRAITS(
short, 4)
198 VIGRA_TYPE_TRAITS(
unsigned short, 5)
199 VIGRA_TYPE_TRAITS(
int, 6)
200 VIGRA_TYPE_TRAITS(
unsigned int, 7)
201 VIGRA_TYPE_TRAITS(
long, 8)
202 VIGRA_TYPE_TRAITS(
unsigned long, 9)
203 VIGRA_TYPE_TRAITS(
float, 10)
204 VIGRA_TYPE_TRAITS(
double, 11)
205 VIGRA_TYPE_TRAITS(
long double, 12)
207 VIGRA_TYPE_TRAITS(
long long, 13)
208 VIGRA_TYPE_TRAITS(
unsigned long long, 14)
211 #undef VIGRA_TYPE_TRAITS
219 struct Not<VigraTrueType>
221 typedef VigraFalseType result;
222 static const bool boolResult =
false;
223 typedef VigraFalseType type;
224 static const bool value =
false;
228 struct Not<VigraFalseType>
230 typedef VigraTrueType result;
231 static const bool boolResult =
true;
232 typedef VigraTrueType type;
233 static const bool value =
true;
236 template <
class L,
class R>
240 struct And<VigraFalseType, VigraFalseType>
242 typedef VigraFalseType result;
243 static const bool boolResult =
false;
244 typedef VigraFalseType type;
245 static const bool value =
false;
249 struct And<VigraFalseType, VigraTrueType>
251 typedef VigraFalseType result;
252 static const bool boolResult =
false;
253 typedef VigraFalseType type;
254 static const bool value =
false;
258 struct And<VigraTrueType, VigraFalseType>
260 typedef VigraFalseType result;
261 static const bool boolResult =
false;
262 typedef VigraFalseType type;
263 static const bool value =
false;
267 struct And<VigraTrueType, VigraTrueType>
269 typedef VigraTrueType result;
270 static const bool boolResult =
true;
271 typedef VigraTrueType type;
272 static const bool value =
true;
275 template <
class L,
class R>
279 struct Or<VigraFalseType, VigraFalseType>
281 typedef VigraFalseType result;
282 static const bool boolResult =
false;
283 typedef VigraFalseType type;
284 static const bool value =
false;
288 struct Or<VigraTrueType, VigraFalseType>
290 typedef VigraTrueType result;
291 static const bool boolResult =
true;
292 typedef VigraTrueType type;
293 static const bool value =
true;
297 struct Or<VigraFalseType, VigraTrueType>
299 typedef VigraTrueType result;
300 static const bool boolResult =
true;
301 typedef VigraTrueType type;
302 static const bool value =
true;
306 struct Or<VigraTrueType, VigraTrueType>
308 typedef VigraTrueType result;
309 static const bool boolResult =
true;
310 typedef VigraTrueType type;
311 static const bool value =
true;
314 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
316 template <
class PREDICATE,
class TRUECASE,
class FALSECASE>
319 template <
class TRUECASE,
class FALSECASE>
320 struct If<VigraTrueType, TRUECASE, FALSECASE>
322 typedef TRUECASE type;
325 template <
class TRUECASE,
class FALSECASE>
326 struct If<VigraFalseType, TRUECASE, FALSECASE>
328 typedef FALSECASE type;
331 template <
bool PREDICATE,
class TRUECASE,
class FALSECASE>
334 template <
class TRUECASE,
class FALSECASE>
335 struct IfBool<true, TRUECASE, FALSECASE>
337 typedef TRUECASE type;
340 template <
class TRUECASE,
class FALSECASE>
341 struct IfBool<false, TRUECASE, FALSECASE>
343 typedef FALSECASE type;
346 template <
class L,
class R>
349 typedef VigraFalseType result;
350 static const bool boolResult =
false;
351 typedef VigraFalseType type;
352 static const bool value =
false;
356 struct IsSameType<T, T>
358 typedef VigraTrueType result;
359 static const bool boolResult =
true;
360 typedef VigraTrueType type;
361 static const bool value =
true;
364 template <
class L,
class R>
365 struct IsDifferentType
367 typedef VigraTrueType type;
368 static const bool value =
true;
372 struct IsDifferentType<T, T>
374 typedef VigraFalseType type;
375 static const bool value =
false;
378 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
380 template <
class From,
class To>
381 struct IsConvertibleTo
383 typedef char falseResult[1];
384 typedef char trueResult[2];
386 static From
const & check();
388 static falseResult * testIsConvertible(...);
389 static trueResult * testIsConvertible(To
const &);
391 enum { resultSize =
sizeof(*testIsConvertible(check())) };
393 static const bool value = (resultSize == 2);
395 IfBool<value, VigraTrueType, VigraFalseType>::type
399 template <
class DERIVED,
class BASE>
402 typedef char falseResult[1];
403 typedef char trueResult[2];
405 static falseResult * testIsDerivedFrom(...);
406 static trueResult * testIsDerivedFrom(BASE
const *);
408 enum { resultSize =
sizeof(*testIsDerivedFrom(static_cast<DERIVED const *>(0))) };
410 static const bool value = (resultSize == 2);
412 IfBool<value, VigraTrueType, VigraFalseType>::type
415 static const bool boolResult = value;
420 struct UnqualifiedType
423 static const bool isConst =
false;
424 static const bool isReference =
false;
425 static const bool isPointer =
false;
429 struct UnqualifiedType<T const>
432 static const bool isConst =
true;
433 static const bool isReference =
false;
434 static const bool isPointer =
false;
438 struct UnqualifiedType<T &>
439 :
public UnqualifiedType<T>
441 static const bool isReference =
true;
445 struct UnqualifiedType<T const &>
446 :
public UnqualifiedType<T const>
448 static const bool isReference =
true;
452 struct UnqualifiedType<T *>
453 :
public UnqualifiedType<T>
455 static const bool isPointer =
true;
459 struct UnqualifiedType<T const *>
460 :
public UnqualifiedType<T const>
462 static const bool isPointer =
true;
465 template <
bool,
class T =
void>
468 struct enable_if<true, T> {
typedef T type; };
472 template <
class T,
template<
class>
class USER>
475 typedef char falseResult[1];
476 typedef char trueResult[2];
478 static falseResult * test(...);
479 static trueResult * test(USER<sfinae_void>);
481 enum { resultSize =
sizeof(*test(static_cast<T*>(0))) };
483 static const bool value = (resultSize == 2);
485 IfBool<value, VigraTrueType, VigraFalseType>::type
490 struct has_argument_type :
public sfinae_test<T, has_argument_type>
492 template <
class U> has_argument_type(U*,
typename U::argument_type* = 0);
496 struct has_result_type :
public sfinae_test<T, has_result_type>
498 template <
class U> has_result_type(U*,
typename U::result_type* = 0);
502 struct has_value_type :
public sfinae_test<T, has_value_type>
504 template <
class U> has_value_type(U*,
typename U::value_type* = 0);
508 struct IsIterator :
public sfinae_test<T, IsIterator>
510 template <
class U> IsIterator(U*,
typename U::iterator_category* = 0);
514 struct IsIterator<T*>
516 static const bool value =
true;
517 typedef VigraTrueType type;
521 struct IsIterator<T const *>
523 static const bool value =
true;
524 typedef VigraTrueType type;
528 struct has_real_promote_type :
public sfinae_test<T, has_real_promote_type>
531 has_real_promote_type(U*,
typename U::real_promote_type* = 0);
534 template <class T, bool P = has_real_promote_type<T>::value>
535 struct get_optional_real_promote
540 struct get_optional_real_promote<T, true>
542 typedef typename T::real_promote_type type;
548 typedef char falseResult[1];
549 typedef char trueResult[2];
551 static falseResult * test(...);
552 template <
class U,
unsigned n>
553 static trueResult * test(U (*)[n]);
555 enum { resultSize =
sizeof(*test(static_cast<T*>(0))) };
557 static const bool value = (resultSize == 2);
559 IfBool<value, VigraTrueType, VigraFalseType>::type
564 template <
class D,
class B,
class Z>
inline
565 D & static_cast_2(Z & z)
567 return static_cast<D &
>(
static_cast<B &
>(z));
571 class copy_if_same_as
575 copy_if_same_as(
const copy_if_same_as &);
576 void operator=(
const copy_if_same_as &);
578 copy_if_same_as(
const A & x,
const A & y)
579 : copied(&x == &y), data(copied ? new A(y) : &x) {}
585 const A & operator()()
const {
return *data; }
590 struct true_test :
public VigraTrueType {};
593 struct false_test : VigraFalseType {};
595 template <
class PC,
class T,
class F>
598 static const bool value = IfBool<PC::value, T, F>::type::value;
604 template <
class A,
class B>
605 static const A & at(
const A & a,
const B &) {
return a; }
606 template <
class A,
class B>
607 static A & at( A & a, B &) {
return a; }
610 struct choose_type<false>
612 template <
class A,
class B>
613 static const B & at(
const A &,
const B & b) {
return b; }
614 template <
class A,
class B>
615 static B & at( A &, B & b) {
return b; }
621 static const bool value = !std::numeric_limits<X>::is_signed
622 && std::numeric_limits<X>::is_integer;
625 struct EnableMetaLog2
626 :
public enable_if<HasMetaLog2<X>::value> {};
628 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
631 template <
class X =
unsigned long,
632 X n = ~(X(0)),
unsigned s = 1,
unsigned t = 0,
bool q = 1,
633 X m = 0, X z = 0, X u = 1,
class =
void>
635 :
public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
637 template <
class X, X n,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
638 struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
640 static const unsigned value
641 = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
643 template <
class X,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
644 struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
646 static const unsigned value
647 = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
649 template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
650 struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
652 static const unsigned value = 2;
654 template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
655 struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
657 static const unsigned value = 1;
659 template <
class X, X z, X u>
660 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
664 static const unsigned value = 0;
667 template <
int X,
unsigned int N>
670 static const long long value = MetaPow<X, N-1>::value * X;
676 static const long long value = 1;
685 template<
class HEAD,
class TAIL=
void>
688 typedef TypeList<HEAD, TAIL> type;
693 template <
class List,
class T>
696 template <
class Head,
class Tail,
class T>
697 struct Contains<TypeList<Head, Tail>, T>
699 typedef typename Contains<Tail, T>::type type;
702 template <
class Head,
class Tail>
703 struct Contains<TypeList<Head, Tail>, Head>
705 typedef VigraTrueType type;
709 struct Contains<void, T>
711 typedef VigraFalseType type;
714 template <
class List,
class T>
717 template <
class Head,
class Tail,
class T>
718 struct Remove<TypeList<Head, Tail>, T>
720 typedef TypeList<Head, typename Remove<Tail, T>::type> type;
723 template <
class Head,
class Tail>
724 struct Remove<TypeList<Head, Tail>, Head>
730 struct Remove<void, T>
735 template <
class A,
class Tail=
void>
738 typedef TypeList<A, typename Tail::type> type;
741 template <
class Head,
class Tail,
class List>
742 struct Push<TypeList<Head, Tail>, List>
744 typedef typename Push<Tail, List>::type Rest;
745 typedef TypeList<Head, Rest> type;
748 template <
class Head,
class Tail>
749 struct Push<TypeList<Head, Tail>, void>
751 typedef TypeList<Head, Tail> type;
757 typedef TypeList<A> type;
767 struct Push<void, void>
772 template <
class A,
class Tail=
void>
775 typedef typename Contains<Tail, A>::type AlreadyInList;
776 typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
779 template <
class Head,
class Tail,
class List>
780 struct PushUnique<TypeList<Head, Tail>, List>
782 typedef typename PushUnique<Tail, List>::type Rest;
783 typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
784 typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
787 template <
class Head,
class Tail>
788 struct PushUnique<TypeList<Head, Tail>, void>
790 typedef TypeList<Head, Tail> type;
794 struct PushUnique<A, void>
796 typedef TypeList<A> type;
800 struct PushUnique<void, A>
806 struct PushUnique<void, void>
811 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
812 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
813 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
814 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
817 typedef typename Push<T19, T20>::type L19;
818 typedef typename Push<T18, L19>::type L18;
819 typedef typename Push<T17, L18>::type L17;
820 typedef typename Push<T16, L17>::type L16;
821 typedef typename Push<T15, L16>::type L15;
822 typedef typename Push<T14, L15>::type L14;
823 typedef typename Push<T13, L14>::type L13;
824 typedef typename Push<T12, L13>::type L12;
825 typedef typename Push<T11, L12>::type L11;
826 typedef typename Push<T10, L11>::type L10;
827 typedef typename Push<T09, L10>::type L09;
828 typedef typename Push<T08, L09>::type L08;
829 typedef typename Push<T07, L08>::type L07;
830 typedef typename Push<T06, L07>::type L06;
831 typedef typename Push<T05, L06>::type L05;
832 typedef typename Push<T04, L05>::type L04;
833 typedef typename Push<T03, L04>::type L03;
834 typedef typename Push<T02, L03>::type L02;
835 typedef typename Push<T01, L02>::type L01;
839 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
840 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
841 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
842 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
843 struct MakeTypeListUnique
845 typedef typename PushUnique<T19, T20>::type L19;
846 typedef typename PushUnique<T18, L19>::type L18;
847 typedef typename PushUnique<T17, L18>::type L17;
848 typedef typename PushUnique<T16, L17>::type L16;
849 typedef typename PushUnique<T15, L16>::type L15;
850 typedef typename PushUnique<T14, L15>::type L14;
851 typedef typename PushUnique<T13, L14>::type L13;
852 typedef typename PushUnique<T12, L13>::type L12;
853 typedef typename PushUnique<T11, L12>::type L11;
854 typedef typename PushUnique<T10, L11>::type L10;
855 typedef typename PushUnique<T09, L10>::type L09;
856 typedef typename PushUnique<T08, L09>::type L08;
857 typedef typename PushUnique<T07, L08>::type L07;
858 typedef typename PushUnique<T06, L07>::type L06;
859 typedef typename PushUnique<T05, L06>::type L05;
860 typedef typename PushUnique<T04, L05>::type L04;
861 typedef typename PushUnique<T03, L04>::type L03;
862 typedef typename PushUnique<T02, L03>::type L02;
863 typedef typename PushUnique<T01, L02>::type L01;
868 #if defined(_MSC_VER)
869 #pragma warning( pop )
Definition: metaprogramming.hxx:105
Definition: metaprogramming.hxx:112
Definition: metaprogramming.hxx:119