36 #ifndef VIGRA_METAPROGRAMMING_HXX
37 #define VIGRA_METAPROGRAMMING_HXX
48 #pragma warning( push )
49 #pragma warning( disable : 4503 )
56 static const int value = N;
59 template <
int N1,
int N2>
63 static const int value = N1 < N2 ? N2 : N1;
66 template <
int N1,
int N2>
70 static const int value = N1 < N2 ? N1 : N2;
75 static const bool asBool =
true, value =
true;
80 static const bool asBool =
false, value =
false;
126 typedef VigraFalseType isConst;
127 typedef VigraFalseType isPOD;
128 typedef VigraFalseType isBuiltinType;
131 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
134 class TypeTraits<T const>
135 :
public TypeTraits<T>
138 typedef VigraTrueType isConst;
142 class TypeTraits<T *>
145 typedef VigraFalseType isConst;
146 typedef VigraTrueType isPOD;
147 typedef VigraTrueType isBuiltinType;
151 class TypeTraits<T const *>
154 typedef VigraFalseType isConst;
155 typedef VigraTrueType isPOD;
156 typedef VigraTrueType isBuiltinType;
159 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
168 #define VIGRA_TYPE_TRAITS(type, size) \
170 class TypeTraits<type> \
173 typedef VigraFalseType isConst; \
174 typedef VigraTrueType isPOD; \
175 typedef VigraTrueType isBuiltinType; \
176 typedef char TypeToSize[size]; \
180 TypeTraits<type>::TypeToSize * typeToSize(type); \
183 struct SizeToType<size> \
185 typedef type result; \
189 VIGRA_TYPE_TRAITS(
char, 1)
190 VIGRA_TYPE_TRAITS(
signed char, 2)
191 VIGRA_TYPE_TRAITS(
unsigned char, 3)
192 VIGRA_TYPE_TRAITS(
short, 4)
193 VIGRA_TYPE_TRAITS(
unsigned short, 5)
194 VIGRA_TYPE_TRAITS(
int, 6)
195 VIGRA_TYPE_TRAITS(
unsigned int, 7)
196 VIGRA_TYPE_TRAITS(
long, 8)
197 VIGRA_TYPE_TRAITS(
unsigned long, 9)
198 VIGRA_TYPE_TRAITS(
float, 10)
199 VIGRA_TYPE_TRAITS(
double, 11)
200 VIGRA_TYPE_TRAITS(
long double, 12)
202 VIGRA_TYPE_TRAITS(
long long, 13)
203 VIGRA_TYPE_TRAITS(
unsigned long long, 14)
206 #undef VIGRA_TYPE_TRAITS
214 struct Not<VigraTrueType>
216 typedef VigraFalseType result;
217 static const bool boolResult =
false;
218 typedef VigraFalseType type;
219 static const bool value =
false;
223 struct Not<VigraFalseType>
225 typedef VigraTrueType result;
226 static const bool boolResult =
true;
227 typedef VigraTrueType type;
228 static const bool value =
true;
231 template <
class L,
class R>
235 struct And<VigraFalseType, VigraFalseType>
237 typedef VigraFalseType result;
238 static const bool boolResult =
false;
239 typedef VigraFalseType type;
240 static const bool value =
false;
244 struct And<VigraFalseType, VigraTrueType>
246 typedef VigraFalseType result;
247 static const bool boolResult =
false;
248 typedef VigraFalseType type;
249 static const bool value =
false;
253 struct And<VigraTrueType, VigraFalseType>
255 typedef VigraFalseType result;
256 static const bool boolResult =
false;
257 typedef VigraFalseType type;
258 static const bool value =
false;
262 struct And<VigraTrueType, VigraTrueType>
264 typedef VigraTrueType result;
265 static const bool boolResult =
true;
266 typedef VigraTrueType type;
267 static const bool value =
true;
270 template <
class L,
class R>
274 struct Or<VigraFalseType, VigraFalseType>
276 typedef VigraFalseType result;
277 static const bool boolResult =
false;
278 typedef VigraFalseType type;
279 static const bool value =
false;
283 struct Or<VigraTrueType, VigraFalseType>
285 typedef VigraTrueType result;
286 static const bool boolResult =
true;
287 typedef VigraTrueType type;
288 static const bool value =
true;
292 struct Or<VigraFalseType, VigraTrueType>
294 typedef VigraTrueType result;
295 static const bool boolResult =
true;
296 typedef VigraTrueType type;
297 static const bool value =
true;
301 struct Or<VigraTrueType, VigraTrueType>
303 typedef VigraTrueType result;
304 static const bool boolResult =
true;
305 typedef VigraTrueType type;
306 static const bool value =
true;
309 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
311 template <
class PREDICATE,
class TRUECASE,
class FALSECASE>
314 template <
class TRUECASE,
class FALSECASE>
315 struct If<VigraTrueType, TRUECASE, FALSECASE>
317 typedef TRUECASE type;
320 template <
class TRUECASE,
class FALSECASE>
321 struct If<VigraFalseType, TRUECASE, FALSECASE>
323 typedef FALSECASE type;
326 template <
bool PREDICATE,
class TRUECASE,
class FALSECASE>
329 template <
class TRUECASE,
class FALSECASE>
330 struct IfBool<true, TRUECASE, FALSECASE>
332 typedef TRUECASE type;
335 template <
class TRUECASE,
class FALSECASE>
336 struct IfBool<false, TRUECASE, FALSECASE>
338 typedef FALSECASE type;
341 template <
class L,
class R>
344 typedef VigraFalseType result;
345 static const bool boolResult =
false;
346 typedef VigraFalseType type;
347 static const bool value =
false;
351 struct IsSameType<T, T>
353 typedef VigraTrueType result;
354 static const bool boolResult =
true;
355 typedef VigraTrueType type;
356 static const bool value =
true;
359 template <
class L,
class R>
360 struct IsDifferentType
362 typedef VigraTrueType type;
363 static const bool value =
true;
367 struct IsDifferentType<T, T>
369 typedef VigraFalseType type;
370 static const bool value =
false;
373 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
375 template <
class From,
class To>
376 struct IsConvertibleTo
378 typedef char falseResult[1];
379 typedef char trueResult[2];
381 static From
const & check();
383 static falseResult * testIsConvertible(...);
384 static trueResult * testIsConvertible(To
const &);
386 enum { resultSize =
sizeof(*testIsConvertible(check())) };
388 static const bool value = (resultSize == 2);
390 IfBool<value, VigraTrueType, VigraFalseType>::type
394 template <
class DERIVED,
class BASE>
397 typedef char falseResult[1];
398 typedef char trueResult[2];
400 static falseResult * testIsDerivedFrom(...);
401 static trueResult * testIsDerivedFrom(BASE
const *);
403 enum { resultSize =
sizeof(*testIsDerivedFrom(static_cast<DERIVED const *>(0))) };
405 static const bool value = (resultSize == 2);
407 IfBool<value, VigraTrueType, VigraFalseType>::type
410 static const bool boolResult = value;
415 struct UnqualifiedType
418 static const bool isConst =
false;
419 static const bool isReference =
false;
420 static const bool isPointer =
false;
424 struct UnqualifiedType<T const>
427 static const bool isConst =
true;
428 static const bool isReference =
false;
429 static const bool isPointer =
false;
433 struct UnqualifiedType<T &>
434 :
public UnqualifiedType<T>
436 static const bool isReference =
true;
440 struct UnqualifiedType<T const &>
441 :
public UnqualifiedType<T const>
443 static const bool isReference =
true;
447 struct UnqualifiedType<T *>
448 :
public UnqualifiedType<T>
450 static const bool isPointer =
true;
454 struct UnqualifiedType<T const *>
455 :
public UnqualifiedType<T const>
457 static const bool isPointer =
true;
460 template <
bool,
class T =
void>
463 struct enable_if<true, T> {
typedef T type; };
467 template <
class T,
template<
class>
class USER>
470 typedef char falseResult[1];
471 typedef char trueResult[2];
473 static falseResult * test(...);
474 static trueResult * test(USER<sfinae_void>);
476 enum { resultSize =
sizeof(*test(static_cast<T*>(0))) };
478 static const bool value = (resultSize == 2);
480 IfBool<value, VigraTrueType, VigraFalseType>::type
485 struct has_argument_type :
public sfinae_test<T, has_argument_type>
487 template <
class U> has_argument_type(U*,
typename U::argument_type* = 0);
491 struct has_result_type :
public sfinae_test<T, has_result_type>
493 template <
class U> has_result_type(U*,
typename U::result_type* = 0);
497 struct has_value_type :
public sfinae_test<T, has_value_type>
499 template <
class U> has_value_type(U*,
typename U::value_type* = 0);
503 struct IsIterator :
public sfinae_test<T, IsIterator>
505 template <
class U> IsIterator(U*,
typename U::iterator_category* = 0);
509 struct IsIterator<T*>
511 static const bool value =
true;
512 typedef VigraTrueType type;
516 struct IsIterator<T const *>
518 static const bool value =
true;
519 typedef VigraTrueType type;
523 struct has_real_promote_type :
public sfinae_test<T, has_real_promote_type>
526 has_real_promote_type(U*,
typename U::real_promote_type* = 0);
529 template <class T, bool P = has_real_promote_type<T>::value>
530 struct get_optional_real_promote
535 struct get_optional_real_promote<T, true>
537 typedef typename T::real_promote_type type;
543 typedef char falseResult[1];
544 typedef char trueResult[2];
546 static falseResult * test(...);
547 template <
class U,
unsigned n>
548 static trueResult * test(U (*)[n]);
550 enum { resultSize =
sizeof(*test(static_cast<T*>(0))) };
552 static const bool value = (resultSize == 2);
554 IfBool<value, VigraTrueType, VigraFalseType>::type
559 template <
class D,
class B,
class Z>
inline
560 D & static_cast_2(Z & z)
562 return static_cast<D &
>(
static_cast<B &
>(z));
566 class copy_if_same_as
570 copy_if_same_as(
const copy_if_same_as &);
571 void operator=(
const copy_if_same_as &);
573 copy_if_same_as(
const A & x,
const A & y)
574 : copied(&x == &y), data(copied ? new A(y) : &x) {}
580 const A & operator()()
const {
return *data; }
585 struct true_test :
public VigraTrueType {};
588 struct false_test : VigraFalseType {};
590 template <
class PC,
class T,
class F>
593 static const bool value = IfBool<PC::value, T, F>::type::value;
599 template <
class A,
class B>
600 static const A & at(
const A & a,
const B &) {
return a; }
601 template <
class A,
class B>
602 static A & at( A & a, B &) {
return a; }
605 struct choose_type<false>
607 template <
class A,
class B>
608 static const B & at(
const A &,
const B & b) {
return b; }
609 template <
class A,
class B>
610 static B & at( A &, B & b) {
return b; }
616 static const bool value = !std::numeric_limits<X>::is_signed
617 && std::numeric_limits<X>::is_integer;
620 struct EnableMetaLog2
621 :
public enable_if<HasMetaLog2<X>::value> {};
623 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
626 template <
class X =
unsigned long,
627 X n = ~(X(0)),
unsigned s = 1,
unsigned t = 0,
bool q = 1,
628 X m = 0, X z = 0, X u = 1,
class =
void>
630 :
public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
632 template <
class X, X n,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
633 struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
635 static const unsigned value
636 = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
638 template <
class X,
unsigned s,
unsigned t,
bool q, X m, X z, X u>
639 struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
641 static const unsigned value
642 = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
644 template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
645 struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
647 static const unsigned value = 2;
649 template <
class X,
unsigned s,
unsigned t,
bool q, X z, X u>
650 struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
652 static const unsigned value = 1;
654 template <
class X, X z, X u>
655 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
659 static const unsigned value = 0;
662 template <
int X,
unsigned int N>
665 static const long long value = MetaPow<X, N-1>::value * X;
671 static const long long value = 1;
680 template<
class HEAD,
class TAIL=
void>
683 typedef TypeList<HEAD, TAIL> type;
688 template <
class List,
class T>
691 template <
class Head,
class Tail,
class T>
692 struct Contains<TypeList<Head, Tail>, T>
694 typedef typename Contains<Tail, T>::type type;
697 template <
class Head,
class Tail>
698 struct Contains<TypeList<Head, Tail>, Head>
700 typedef VigraTrueType type;
704 struct Contains<void, T>
706 typedef VigraFalseType type;
709 template <
class List,
class T>
712 template <
class Head,
class Tail,
class T>
713 struct Remove<TypeList<Head, Tail>, T>
715 typedef TypeList<Head, typename Remove<Tail, T>::type> type;
718 template <
class Head,
class Tail>
719 struct Remove<TypeList<Head, Tail>, Head>
725 struct Remove<void, T>
730 template <
class A,
class Tail=
void>
733 typedef TypeList<A, typename Tail::type> type;
736 template <
class Head,
class Tail,
class List>
737 struct Push<TypeList<Head, Tail>, List>
739 typedef typename Push<Tail, List>::type Rest;
740 typedef TypeList<Head, Rest> type;
743 template <
class Head,
class Tail>
744 struct Push<TypeList<Head, Tail>, void>
746 typedef TypeList<Head, Tail> type;
752 typedef TypeList<A> type;
762 struct Push<void, void>
767 template <
class A,
class Tail=
void>
770 typedef typename Contains<Tail, A>::type AlreadyInList;
771 typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
774 template <
class Head,
class Tail,
class List>
775 struct PushUnique<TypeList<Head, Tail>, List>
777 typedef typename PushUnique<Tail, List>::type Rest;
778 typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
779 typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
782 template <
class Head,
class Tail>
783 struct PushUnique<TypeList<Head, Tail>, void>
785 typedef TypeList<Head, Tail> type;
789 struct PushUnique<A, void>
791 typedef TypeList<A> type;
795 struct PushUnique<void, A>
801 struct PushUnique<void, void>
806 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
807 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
808 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
809 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
812 typedef typename Push<T19, T20>::type L19;
813 typedef typename Push<T18, L19>::type L18;
814 typedef typename Push<T17, L18>::type L17;
815 typedef typename Push<T16, L17>::type L16;
816 typedef typename Push<T15, L16>::type L15;
817 typedef typename Push<T14, L15>::type L14;
818 typedef typename Push<T13, L14>::type L13;
819 typedef typename Push<T12, L13>::type L12;
820 typedef typename Push<T11, L12>::type L11;
821 typedef typename Push<T10, L11>::type L10;
822 typedef typename Push<T09, L10>::type L09;
823 typedef typename Push<T08, L09>::type L08;
824 typedef typename Push<T07, L08>::type L07;
825 typedef typename Push<T06, L07>::type L06;
826 typedef typename Push<T05, L06>::type L05;
827 typedef typename Push<T04, L05>::type L04;
828 typedef typename Push<T03, L04>::type L03;
829 typedef typename Push<T02, L03>::type L02;
830 typedef typename Push<T01, L02>::type L01;
834 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
835 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
836 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
837 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
838 struct MakeTypeListUnique
840 typedef typename PushUnique<T19, T20>::type L19;
841 typedef typename PushUnique<T18, L19>::type L18;
842 typedef typename PushUnique<T17, L18>::type L17;
843 typedef typename PushUnique<T16, L17>::type L16;
844 typedef typename PushUnique<T15, L16>::type L15;
845 typedef typename PushUnique<T14, L15>::type L14;
846 typedef typename PushUnique<T13, L14>::type L13;
847 typedef typename PushUnique<T12, L13>::type L12;
848 typedef typename PushUnique<T11, L12>::type L11;
849 typedef typename PushUnique<T10, L11>::type L10;
850 typedef typename PushUnique<T09, L10>::type L09;
851 typedef typename PushUnique<T08, L09>::type L08;
852 typedef typename PushUnique<T07, L08>::type L07;
853 typedef typename PushUnique<T06, L07>::type L06;
854 typedef typename PushUnique<T05, L06>::type L05;
855 typedef typename PushUnique<T04, L05>::type L04;
856 typedef typename PushUnique<T03, L04>::type L03;
857 typedef typename PushUnique<T02, L03>::type L02;
858 typedef typename PushUnique<T01, L02>::type L01;
863 #if defined(_MSC_VER)
864 #pragma warning( pop )