[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/metaprogramming.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
00033 /*                                                                      */
00034 /************************************************************************/
00035 
00036 #ifndef VIGRA_METAPROGRAMMING_HXX
00037 #define VIGRA_METAPROGRAMMING_HXX
00038 
00039 #include "config.hxx"
00040 #include <climits>
00041 #include <limits>
00042 #include <algorithm>
00043 
00044 namespace vigra {
00045 
00046 // mask cl.exe shortcomings [begin]
00047 #if defined(_MSC_VER)
00048 #pragma warning( push )
00049 #pragma warning( disable : 4503 )
00050 #endif
00051 
00052 template <int N>
00053 class MetaInt
00054 {
00055   public:
00056     static const int value = N;
00057 };
00058 
00059 template <int N1, int N2>
00060 class MetaMax
00061 {
00062   public:
00063     static const int value = N1 < N2 ? N2 : N1;
00064 };
00065 
00066 template <int N1, int N2>
00067 class MetaMin
00068 {
00069   public:
00070     static const int value = N1 < N2 ? N1 : N2;
00071 };
00072 
00073 struct VigraTrueType
00074 {
00075    static const bool asBool = true, value = true;
00076 };
00077 
00078 struct VigraFalseType
00079 {
00080     static const bool asBool = false, value = false;
00081 };
00082 
00083 /**  \addtogroup MultiArrayTags Multi-dimensional Array Tags
00084       Meta-programming tags to mark array's as strided or unstrided.
00085 */
00086 
00087 //@{
00088 
00089 /********************************************************/
00090 /*                                                      */
00091 /*                   StridedArrayTag                    */
00092 /*                                                      */
00093 /********************************************************/
00094 
00095 /** tag for marking a MultiArray strided.
00096 
00097 <b>\#include</b>
00098 <vigra/multi_array.hxx>
00099 
00100 Namespace: vigra
00101 */
00102 struct StridedArrayTag {};
00103 
00104 /********************************************************/
00105 /*                                                      */
00106 /*                  UnstridedArrayTag                   */
00107 /*                                                      */
00108 /********************************************************/
00109 
00110 /** tag for marking a MultiArray unstrided.
00111 
00112 <b>\#include</b>
00113 <vigra/multi_array.hxx>
00114 
00115 Namespace: vigra
00116 */
00117 struct UnstridedArrayTag {};
00118 
00119 template<class T>
00120 class TypeTraits
00121 {
00122   public:
00123     typedef VigraFalseType isConst;
00124     typedef VigraFalseType isPOD;
00125     typedef VigraFalseType isBuiltinType;
00126 };
00127 
00128 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
00129 
00130 template<class T>
00131 class TypeTraits<T const>
00132 : public TypeTraits<T>
00133 {
00134   public:
00135     typedef VigraTrueType isConst;
00136 };
00137 
00138 template<class T> 
00139 class TypeTraits<T *>
00140 {
00141   public:
00142     typedef VigraFalseType isConst;
00143     typedef VigraTrueType isPOD;
00144     typedef VigraTrueType isBuiltinType;
00145 };
00146 
00147 template<class T> 
00148 class TypeTraits<T const *>
00149 {
00150   public:
00151     typedef VigraFalseType isConst;
00152     typedef VigraTrueType isPOD;
00153     typedef VigraTrueType isBuiltinType;
00154 };
00155 
00156 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00157 
00158 namespace detail {
00159 
00160 template <int size>
00161 struct SizeToType;
00162 
00163 } // namespace detail 
00164 
00165 #define VIGRA_TYPE_TRAITS(type, size) \
00166 template<> \
00167 class TypeTraits<type> \
00168 { \
00169   public: \
00170     typedef VigraFalseType isConst; \
00171     typedef VigraTrueType isPOD; \
00172     typedef VigraTrueType isBuiltinType; \
00173     typedef char TypeToSize[size]; \
00174 }; \
00175  \
00176 namespace detail { \
00177   TypeTraits<type>::TypeToSize * typeToSize(type); \
00178   \
00179   template <> \
00180   struct SizeToType<size> \
00181   { \
00182       typedef type result; \
00183   }; \
00184 } 
00185 
00186 VIGRA_TYPE_TRAITS(char, 1)
00187 VIGRA_TYPE_TRAITS(signed char, 2)
00188 VIGRA_TYPE_TRAITS(unsigned char, 3)
00189 VIGRA_TYPE_TRAITS(short, 4)
00190 VIGRA_TYPE_TRAITS(unsigned short, 5)
00191 VIGRA_TYPE_TRAITS(int, 6)
00192 VIGRA_TYPE_TRAITS(unsigned int, 7)
00193 VIGRA_TYPE_TRAITS(long, 8)
00194 VIGRA_TYPE_TRAITS(unsigned long, 9)
00195 VIGRA_TYPE_TRAITS(float, 10)
00196 VIGRA_TYPE_TRAITS(double, 11)
00197 VIGRA_TYPE_TRAITS(long double, 12)
00198 #ifdef LLONG_MAX
00199 VIGRA_TYPE_TRAITS(long long, 13)
00200 VIGRA_TYPE_TRAITS(unsigned long long, 14)
00201 #endif
00202 
00203 #undef VIGRA_TYPE_TRAITS
00204 
00205 //@}
00206 
00207 template <class A>
00208 struct Not;
00209 
00210 template <>
00211 struct Not<VigraTrueType>
00212 {
00213     typedef VigraFalseType result;        // deprecated
00214     static const bool boolResult = false; // deprecated
00215     typedef VigraFalseType type;
00216     static const bool value = false;
00217 };
00218 
00219 template <>
00220 struct Not<VigraFalseType>
00221 {
00222     typedef VigraTrueType result;        // deprecated
00223     static const bool boolResult = true; // deprecated
00224     typedef VigraTrueType type;
00225     static const bool value = true;
00226 };
00227 
00228 template <class L, class R>
00229 struct And;
00230 
00231 template <>
00232 struct And<VigraFalseType, VigraFalseType>
00233 {
00234     typedef VigraFalseType result;        // deprecated
00235     static const bool boolResult = false; // deprecated
00236     typedef VigraFalseType type;
00237     static const bool value = false;
00238 };
00239 
00240 template <>
00241 struct And<VigraFalseType, VigraTrueType>
00242 {
00243     typedef VigraFalseType result;        // deprecated
00244     static const bool boolResult = false; // deprecated
00245     typedef VigraFalseType type;
00246     static const bool value = false;
00247 };
00248 
00249 template <>
00250 struct And<VigraTrueType, VigraFalseType>
00251 {
00252     typedef VigraFalseType result;        // deprecated
00253     static const bool boolResult = false; // deprecated
00254     typedef VigraFalseType type;
00255     static const bool value = false;
00256 };
00257 
00258 template <>
00259 struct And<VigraTrueType, VigraTrueType>
00260 {
00261     typedef VigraTrueType result;        // deprecated
00262     static const bool boolResult = true; // deprecated
00263     typedef VigraTrueType type;
00264     static const bool value = true;
00265 };
00266 
00267 template <class L, class R>
00268 struct Or;
00269 
00270 template <>
00271 struct Or<VigraFalseType, VigraFalseType>
00272 {
00273     typedef VigraFalseType result;        // deprecated
00274     static const bool boolResult = false; // deprecated
00275     typedef VigraFalseType type;
00276     static const bool value = false;
00277 };
00278 
00279 template <>
00280 struct Or<VigraTrueType, VigraFalseType>
00281 {
00282     typedef VigraTrueType result;        // deprecated
00283     static const bool boolResult = true; // deprecated
00284     typedef VigraTrueType type;
00285     static const bool value = true;
00286 };
00287 
00288 template <>
00289 struct Or<VigraFalseType, VigraTrueType>
00290 {
00291     typedef VigraTrueType result;        // deprecated
00292     static const bool boolResult = true; // deprecated
00293     typedef VigraTrueType type;
00294     static const bool value = true;
00295 };
00296 
00297 template <>
00298 struct Or<VigraTrueType, VigraTrueType>
00299 {
00300     typedef VigraTrueType result;        // deprecated
00301     static const bool boolResult = true; // deprecated
00302     typedef VigraTrueType type;
00303     static const bool value = true;
00304 };
00305 
00306 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
00307 
00308 template <class PREDICATE, class TRUECASE, class FALSECASE>
00309 struct If;
00310 
00311 template <class TRUECASE, class FALSECASE>
00312 struct If<VigraTrueType, TRUECASE, FALSECASE>
00313 {
00314     typedef TRUECASE type;
00315 };
00316 
00317 template <class TRUECASE, class FALSECASE>
00318 struct If<VigraFalseType, TRUECASE, FALSECASE>
00319 {
00320     typedef FALSECASE type;
00321 };
00322 
00323 template <bool PREDICATE, class TRUECASE, class FALSECASE>
00324 struct IfBool;
00325 
00326 template <class TRUECASE, class FALSECASE>
00327 struct IfBool<true, TRUECASE, FALSECASE>
00328 {
00329     typedef TRUECASE type;
00330 };
00331 
00332 template <class TRUECASE, class FALSECASE>
00333 struct IfBool<false, TRUECASE, FALSECASE>
00334 {
00335     typedef FALSECASE type;
00336 };
00337 
00338 template <class L, class R>
00339 struct IsSameType
00340 {
00341     typedef VigraFalseType result;        // deprecated
00342     static const bool boolResult = false; // deprecated
00343     typedef VigraFalseType type;
00344     static const bool value = false;
00345 };
00346 
00347 template <class T>
00348 struct IsSameType<T, T>
00349 {
00350     typedef VigraTrueType result;        // deprecated
00351     static const bool boolResult = true; // deprecated
00352     typedef VigraTrueType type;
00353     static const bool value = true;
00354 };
00355 
00356 template <class L, class R>
00357 struct IsDifferentType
00358 {
00359     typedef VigraTrueType type;
00360     static const bool value = true;
00361 };
00362 
00363 template <class T>
00364 struct IsDifferentType<T, T>
00365 {
00366     typedef VigraFalseType type;
00367     static const bool value = false;
00368 };
00369 
00370 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00371 
00372 template <class From, class To>
00373 struct IsConvertibleTo
00374 {
00375     typedef char falseResult[1];
00376     typedef char trueResult[2];
00377     
00378     static From const & check();
00379     
00380     static falseResult * testIsConvertible(...);
00381     static trueResult * testIsConvertible(To const &);
00382     
00383     enum { resultSize = sizeof(*testIsConvertible(check())) };
00384     
00385     static const bool value = (resultSize == 2);
00386     typedef typename 
00387         IfBool<value, VigraTrueType, VigraFalseType>::type
00388         type;
00389 };
00390 
00391 template <class DERIVED, class BASE>
00392 struct IsDerivedFrom
00393 {
00394     typedef char falseResult[1];
00395     typedef char trueResult[2];
00396     
00397     static falseResult * testIsDerivedFrom(...);
00398     static trueResult * testIsDerivedFrom(BASE const *);
00399     
00400     enum { resultSize = sizeof(*testIsDerivedFrom((DERIVED const *)0)) };
00401     
00402     static const bool value = (resultSize == 2);
00403     typedef typename 
00404         IfBool<value, VigraTrueType, VigraFalseType>::type
00405         type;
00406 
00407     static const bool boolResult = value; // deprecated
00408     typedef type result;                  // deprecated
00409 };
00410 
00411 template <class T>
00412 struct UnqualifiedType
00413 {
00414     typedef T type;
00415 };
00416 
00417 template <class T>
00418 struct UnqualifiedType<T const>
00419 {
00420     typedef T type;
00421 };
00422 
00423 template <class T>
00424 struct UnqualifiedType<T &>
00425 : public UnqualifiedType<T>
00426 {};
00427 
00428 template <class T>
00429 struct UnqualifiedType<T const &>
00430 : public UnqualifiedType<T>
00431 {};
00432 
00433 template <class T>
00434 struct UnqualifiedType<T *>
00435 : public UnqualifiedType<T>
00436 {};
00437 
00438 template <class T>
00439 struct UnqualifiedType<T const *>
00440 : public UnqualifiedType<T>
00441 {};
00442 
00443 template <bool, class T = void>
00444 struct enable_if {};
00445 template <class T>
00446 struct enable_if<true, T> { typedef T type; };
00447 
00448 struct sfinae_void;
00449 
00450 template <class T, template<class> class USER>
00451 struct sfinae_test
00452 {
00453     typedef char falseResult[1];
00454     typedef char trueResult[2];
00455     
00456     static falseResult * test(...);
00457     static trueResult * test(USER<sfinae_void>);
00458     
00459     enum { resultSize = sizeof(*test((T*)0)) };
00460     
00461     static const bool value = (resultSize == 2);
00462     typedef typename
00463         IfBool<value, VigraTrueType, VigraFalseType>::type
00464         type;
00465 };
00466 
00467 template <class T>
00468 struct has_argument_type : public sfinae_test<T, has_argument_type>
00469 {
00470     template <class U> has_argument_type(U*, typename U::argument_type* = 0);
00471 };
00472 
00473 template <class T>
00474 struct has_result_type : public sfinae_test<T, has_result_type>
00475 {
00476     template <class U> has_result_type(U*, typename U::result_type* = 0);
00477 };
00478 
00479 template <class T>
00480 struct has_value_type : public sfinae_test<T, has_value_type>
00481 {
00482     template <class U> has_value_type(U*, typename U::value_type* = 0);
00483 };
00484 
00485 template <class T>
00486 struct IsIterator : public sfinae_test<T, IsIterator>
00487 {
00488     template <class U> IsIterator(U*, typename U::iterator_category* = 0);
00489 };
00490 
00491 template <class T>
00492 struct IsIterator<T*>
00493 {
00494     static const bool value = true;
00495     typedef VigraTrueType type;
00496 };
00497 
00498 template <class T>
00499 struct IsIterator<T const *>
00500 {
00501     static const bool value = true;
00502     typedef VigraTrueType type;
00503 };
00504 
00505 template <class T>
00506 struct has_real_promote_type : public sfinae_test<T, has_real_promote_type>
00507 {
00508     template <class U>
00509     has_real_promote_type(U*, typename U::real_promote_type* = 0);
00510 };
00511 
00512 template <class T, bool P = has_real_promote_type<T>::value>
00513 struct get_optional_real_promote
00514 {
00515     typedef T type;
00516 };
00517 template <class T>
00518 struct get_optional_real_promote<T, true>
00519 {
00520     typedef typename T::real_promote_type type;
00521 };
00522 
00523 template <class T>
00524 struct IsArray
00525 {
00526     typedef char falseResult[1];
00527     typedef char trueResult[2];
00528     
00529     static falseResult * test(...);
00530     template <class U, unsigned n>
00531     static trueResult * test(U (*)[n]);
00532     
00533     enum { resultSize = sizeof(*test((T*)0)) };
00534     
00535     static const bool value = (resultSize == 2);
00536     typedef typename
00537         IfBool<value, VigraTrueType, VigraFalseType>::type
00538         type;
00539 };
00540 
00541 
00542 template <class D, class B, class Z> inline
00543 D & static_cast_2(Z & z)
00544 {
00545     return static_cast<D &>(static_cast<B &>(z));
00546 }
00547 
00548 template <class A>
00549 class copy_if_same_as
00550 {
00551     const bool copied;
00552     const A *const data;
00553     copy_if_same_as(const copy_if_same_as &);
00554     void operator=(const copy_if_same_as &);
00555 public:
00556     copy_if_same_as(const A & x, const A & y)
00557         : copied(&x == &y), data(copied ? new A(y) : &x) {}
00558     ~copy_if_same_as()
00559     {
00560         if (copied)
00561             delete data;
00562     }
00563     const A & operator()() const { return *data; }
00564 };
00565 
00566 
00567 template <class>
00568 struct true_test : public VigraTrueType {};
00569 
00570 template <class>
00571 struct false_test : VigraFalseType {};
00572 
00573 template <class PC, class T, class F>
00574 struct ChooseBool
00575 {
00576     static const bool value = IfBool<PC::value, T, F>::type::value;
00577 };
00578 
00579 template <bool>
00580 struct choose_type
00581 {
00582     template <class A, class B>
00583     static const A & at(const A & a, const B &) { return a; }
00584     template <class A, class B>
00585     static       A & at(      A & a,       B &) { return a; }
00586 };
00587 template <>
00588 struct choose_type<false>
00589 {
00590     template <class A, class B>
00591     static const B & at(const A &, const B & b) { return b; }
00592     template <class A, class B>
00593     static       B & at(      A &,       B & b) { return b; }
00594 };
00595 
00596 template <class X>
00597 struct HasMetaLog2
00598 {
00599     static const bool value =   !std::numeric_limits<X>::is_signed
00600                               && std::numeric_limits<X>::is_integer;
00601 };
00602 template <class X>
00603 struct EnableMetaLog2
00604     : public enable_if<HasMetaLog2<X>::value> {};
00605 template <class>
00606 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
00607 
00608 // use a conforming template depth here (below 15 for up to 128 bits)
00609 template <class X = unsigned long,
00610           X n = ~(X(0)), unsigned s = 1, unsigned t = 0, bool q = 1,
00611           X m = 0, X z = 0, X u = 1, class = void>
00612 class MetaLog2
00613     : public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
00614 {};
00615 template <class X, X n, unsigned s, unsigned t, bool q, X m, X z, X u>
00616 struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
00617 {
00618     static const unsigned value
00619         = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
00620 };
00621 template <class X, unsigned s, unsigned t, bool q, X m, X z, X u>
00622 struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
00623 {
00624     static const unsigned value
00625         = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
00626 };
00627 template <class X, unsigned s, unsigned t, bool q, X z, X u>
00628 struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
00629 {
00630     static const unsigned value = 2;
00631 };
00632 template <class X, unsigned s, unsigned t, bool q, X z, X u>
00633 struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
00634 {
00635     static const unsigned value = 1;
00636 };
00637 template <class X, X z, X u>
00638 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
00639 {
00640     // A value of zero for MetaLog2<X, 0> is likely to cause most harm,
00641     // such as division by zero or zero array sizes, this is actually indended.
00642     static const unsigned value = 0;
00643 };
00644 
00645 /****************************************************************************/
00646 /*                                                                          */
00647 /*                        TypeList and its functions                        */
00648 /*                                                                          */
00649 /****************************************************************************/
00650 
00651 template<class HEAD, class TAIL=void>
00652 struct TypeList
00653 {
00654     typedef TypeList<HEAD, TAIL> type;
00655     typedef HEAD Head;
00656     typedef TAIL Tail;
00657 };
00658 
00659 template <class List, class T>
00660 struct Contains;
00661 
00662 template <class Head, class Tail, class T>
00663 struct Contains<TypeList<Head, Tail>, T>
00664 {
00665     typedef typename Contains<Tail, T>::type type;
00666 };
00667 
00668 template <class Head, class Tail>
00669 struct Contains<TypeList<Head, Tail>, Head>
00670 {
00671     typedef VigraTrueType type;
00672 };
00673 
00674 template <class T>
00675 struct Contains<void, T>
00676 {
00677     typedef VigraFalseType type;
00678 };
00679 
00680 template <class List, class T>
00681 struct Remove;
00682 
00683 template <class Head, class Tail, class T>
00684 struct Remove<TypeList<Head, Tail>, T>
00685 {
00686     typedef TypeList<Head, typename Remove<Tail, T>::type> type;
00687 };
00688 
00689 template <class Head, class Tail>
00690 struct Remove<TypeList<Head, Tail>, Head>
00691 {
00692     typedef Tail type;
00693 };
00694 
00695 template <class T>
00696 struct Remove<void, T>
00697 {
00698     typedef void type;
00699 };
00700 
00701 template <class A, class Tail=void>
00702 struct Push
00703 {
00704     typedef TypeList<A, typename Tail::type> type;
00705 };
00706 
00707 template <class Head, class Tail, class List>
00708 struct Push<TypeList<Head, Tail>, List>
00709 {
00710     typedef typename Push<Tail, List>::type Rest;
00711     typedef TypeList<Head, Rest> type;
00712 };
00713 
00714 template <class Head, class Tail>
00715 struct Push<TypeList<Head, Tail>, void>
00716 {
00717     typedef TypeList<Head, Tail> type;
00718 };
00719 
00720 template <class A>
00721 struct Push<A, void>
00722 {
00723     typedef TypeList<A> type;
00724 };
00725 
00726 template <class A>
00727 struct Push<void, A>
00728 {
00729     typedef A type;
00730 };
00731 
00732 template <>
00733 struct Push<void, void>
00734 {
00735     typedef void type;
00736 };
00737 
00738 template <class A, class Tail=void>
00739 struct PushUnique
00740 {
00741     typedef typename Contains<Tail, A>::type AlreadyInList;
00742     typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
00743 };
00744 
00745 template <class Head, class Tail, class List>
00746 struct PushUnique<TypeList<Head, Tail>, List>
00747 {
00748     typedef typename PushUnique<Tail, List>::type Rest;
00749     typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
00750     typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
00751 };
00752 
00753 template <class Head, class Tail>
00754 struct PushUnique<TypeList<Head, Tail>, void>
00755 {
00756     typedef TypeList<Head, Tail> type;
00757 };
00758 
00759 template <class A>
00760 struct PushUnique<A, void>
00761 {
00762     typedef TypeList<A> type;
00763 };
00764 
00765 template <class A>
00766 struct PushUnique<void, A>
00767 {
00768     typedef A type;
00769 };
00770 
00771 template <>
00772 struct PushUnique<void, void>
00773 {
00774     typedef void type;
00775 };
00776 
00777 template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
00778           class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
00779           class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
00780           class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
00781 struct MakeTypeList
00782 {
00783     typedef typename Push<T19, T20>::type L19;
00784     typedef typename Push<T18, L19>::type L18;
00785     typedef typename Push<T17, L18>::type L17;
00786     typedef typename Push<T16, L17>::type L16;
00787     typedef typename Push<T15, L16>::type L15;
00788     typedef typename Push<T14, L15>::type L14;
00789     typedef typename Push<T13, L14>::type L13;
00790     typedef typename Push<T12, L13>::type L12;
00791     typedef typename Push<T11, L12>::type L11;
00792     typedef typename Push<T10, L11>::type L10;
00793     typedef typename Push<T09, L10>::type L09;
00794     typedef typename Push<T08, L09>::type L08;
00795     typedef typename Push<T07, L08>::type L07;
00796     typedef typename Push<T06, L07>::type L06;
00797     typedef typename Push<T05, L06>::type L05;
00798     typedef typename Push<T04, L05>::type L04;
00799     typedef typename Push<T03, L04>::type L03;
00800     typedef typename Push<T02, L03>::type L02;
00801     typedef typename Push<T01, L02>::type L01;
00802     typedef L01 type;
00803 };
00804 
00805 template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
00806           class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
00807           class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
00808           class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
00809 struct MakeTypeListUnique
00810 {
00811     typedef typename PushUnique<T19, T20>::type L19;
00812     typedef typename PushUnique<T18, L19>::type L18;
00813     typedef typename PushUnique<T17, L18>::type L17;
00814     typedef typename PushUnique<T16, L17>::type L16;
00815     typedef typename PushUnique<T15, L16>::type L15;
00816     typedef typename PushUnique<T14, L15>::type L14;
00817     typedef typename PushUnique<T13, L14>::type L13;
00818     typedef typename PushUnique<T12, L13>::type L12;
00819     typedef typename PushUnique<T11, L12>::type L11;
00820     typedef typename PushUnique<T10, L11>::type L10;
00821     typedef typename PushUnique<T09, L10>::type L09;
00822     typedef typename PushUnique<T08, L09>::type L08;
00823     typedef typename PushUnique<T07, L08>::type L07;
00824     typedef typename PushUnique<T06, L07>::type L06;
00825     typedef typename PushUnique<T05, L06>::type L05;
00826     typedef typename PushUnique<T04, L05>::type L04;
00827     typedef typename PushUnique<T03, L04>::type L03;
00828     typedef typename PushUnique<T02, L03>::type L02;
00829     typedef typename PushUnique<T01, L02>::type L01;
00830     typedef L01 type;
00831 };
00832 
00833 // mask cl.exe shortcomings [end]
00834 #if defined(_MSC_VER)
00835 #pragma warning( pop )
00836 #endif
00837 
00838 } // namespace vigra
00839 
00840 #endif /* VIGRA_METAPROGRAMMING_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)