vigra - vigra/metaprogramming.hxx Source File

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

vigra/metaprogramming.hxx |

    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)