[ 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) |
html generated using doxygen and Python
|