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

metaprogramming.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_METAPROGRAMMING_HXX
37 #define VIGRA_METAPROGRAMMING_HXX
38 
39 #include "config.hxx"
40 #include <climits>
41 #include <limits>
42 #include <algorithm>
43 
44 namespace vigra {
45 
46 // mask cl.exe shortcomings [begin]
47 #if defined(_MSC_VER)
48 #pragma warning( push )
49 #pragma warning( disable : 4503 )
50 #endif
51 
52 template <int N>
53 class MetaInt
54 {
55  public:
56  static const int value = N;
57 };
58 
59 template <int N1, int N2>
60 class MetaMax
61 {
62  public:
63  static const int value = N1 < N2 ? N2 : N1;
64 };
65 
66 template <int N1, int N2>
67 class MetaMin
68 {
69  public:
70  static const int value = N1 < N2 ? N1 : N2;
71 };
72 
73 struct VigraTrueType
74 {
75  static const bool asBool = true, value = true;
76 };
77 
78 struct VigraFalseType
79 {
80  static const bool asBool = false, value = false;
81 };
82 
83 /** \addtogroup MultiArrayTags Multi-dimensional Array Tags
84  Meta-programming tags to mark array's as strided or unstrided.
85 */
86 
87 //@{
88 
89 /********************************************************/
90 /* */
91 /* tags for MultiArray memory layout */
92 /* */
93 /********************************************************/
94 
95 /** tag for marking a MultiArray strided.
96 
97  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
98  Namespace: vigra
99 */
100 struct StridedArrayTag {};
101 
102 /** tag for marking a MultiArray unstrided.
103 
104  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
105  Namespace: vigra
106 */
108 
109 /** tag for marking a MultiArray chunked.
110 
111  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
112  Namespace: vigra
113 */
114 struct ChunkedArrayTag {};
115 
116 /********************************************************/
117 /* */
118 /* TypeTraits */
119 /* */
120 /********************************************************/
121 
122 template<class T>
123 class TypeTraits
124 {
125  public:
126  typedef VigraFalseType isConst;
127  typedef VigraFalseType isPOD;
128  typedef VigraFalseType isBuiltinType;
129 };
130 
131 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
132 
133 template<class T>
134 class TypeTraits<T const>
135 : public TypeTraits<T>
136 {
137  public:
138  typedef VigraTrueType isConst;
139 };
140 
141 template<class T>
142 class TypeTraits<T *>
143 {
144  public:
145  typedef VigraFalseType isConst;
146  typedef VigraTrueType isPOD;
147  typedef VigraTrueType isBuiltinType;
148 };
149 
150 template<class T>
151 class TypeTraits<T const *>
152 {
153  public:
154  typedef VigraFalseType isConst;
155  typedef VigraTrueType isPOD;
156  typedef VigraTrueType isBuiltinType;
157 };
158 
159 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
160 
161 namespace detail {
162 
163 template <int size>
164 struct SizeToType;
165 
166 } // namespace detail
167 
168 #define VIGRA_TYPE_TRAITS(type, size) \
169 template<> \
170 class TypeTraits<type> \
171 { \
172  public: \
173  typedef VigraFalseType isConst; \
174  typedef VigraTrueType isPOD; \
175  typedef VigraTrueType isBuiltinType; \
176  typedef char TypeToSize[size]; \
177 }; \
178  \
179 namespace detail { \
180  TypeTraits<type>::TypeToSize * typeToSize(type); \
181  \
182  template <> \
183  struct SizeToType<size> \
184  { \
185  typedef type result; \
186  }; \
187 }
188 
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)
201 #ifdef LLONG_MAX
202 VIGRA_TYPE_TRAITS(long long, 13)
203 VIGRA_TYPE_TRAITS(unsigned long long, 14)
204 #endif
205 
206 #undef VIGRA_TYPE_TRAITS
207 
208 //@}
209 
210 template <class A>
211 struct Not;
212 
213 template <>
214 struct Not<VigraTrueType>
215 {
216  typedef VigraFalseType result; // deprecated
217  static const bool boolResult = false; // deprecated
218  typedef VigraFalseType type;
219  static const bool value = false;
220 };
221 
222 template <>
223 struct Not<VigraFalseType>
224 {
225  typedef VigraTrueType result; // deprecated
226  static const bool boolResult = true; // deprecated
227  typedef VigraTrueType type;
228  static const bool value = true;
229 };
230 
231 template <class L, class R>
232 struct And;
233 
234 template <>
235 struct And<VigraFalseType, VigraFalseType>
236 {
237  typedef VigraFalseType result; // deprecated
238  static const bool boolResult = false; // deprecated
239  typedef VigraFalseType type;
240  static const bool value = false;
241 };
242 
243 template <>
244 struct And<VigraFalseType, VigraTrueType>
245 {
246  typedef VigraFalseType result; // deprecated
247  static const bool boolResult = false; // deprecated
248  typedef VigraFalseType type;
249  static const bool value = false;
250 };
251 
252 template <>
253 struct And<VigraTrueType, VigraFalseType>
254 {
255  typedef VigraFalseType result; // deprecated
256  static const bool boolResult = false; // deprecated
257  typedef VigraFalseType type;
258  static const bool value = false;
259 };
260 
261 template <>
262 struct And<VigraTrueType, VigraTrueType>
263 {
264  typedef VigraTrueType result; // deprecated
265  static const bool boolResult = true; // deprecated
266  typedef VigraTrueType type;
267  static const bool value = true;
268 };
269 
270 template <class L, class R>
271 struct Or;
272 
273 template <>
274 struct Or<VigraFalseType, VigraFalseType>
275 {
276  typedef VigraFalseType result; // deprecated
277  static const bool boolResult = false; // deprecated
278  typedef VigraFalseType type;
279  static const bool value = false;
280 };
281 
282 template <>
283 struct Or<VigraTrueType, VigraFalseType>
284 {
285  typedef VigraTrueType result; // deprecated
286  static const bool boolResult = true; // deprecated
287  typedef VigraTrueType type;
288  static const bool value = true;
289 };
290 
291 template <>
292 struct Or<VigraFalseType, VigraTrueType>
293 {
294  typedef VigraTrueType result; // deprecated
295  static const bool boolResult = true; // deprecated
296  typedef VigraTrueType type;
297  static const bool value = true;
298 };
299 
300 template <>
301 struct Or<VigraTrueType, VigraTrueType>
302 {
303  typedef VigraTrueType result; // deprecated
304  static const bool boolResult = true; // deprecated
305  typedef VigraTrueType type;
306  static const bool value = true;
307 };
308 
309 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
310 
311 template <class PREDICATE, class TRUECASE, class FALSECASE>
312 struct If;
313 
314 template <class TRUECASE, class FALSECASE>
315 struct If<VigraTrueType, TRUECASE, FALSECASE>
316 {
317  typedef TRUECASE type;
318 };
319 
320 template <class TRUECASE, class FALSECASE>
321 struct If<VigraFalseType, TRUECASE, FALSECASE>
322 {
323  typedef FALSECASE type;
324 };
325 
326 template <bool PREDICATE, class TRUECASE, class FALSECASE>
327 struct IfBool;
328 
329 template <class TRUECASE, class FALSECASE>
330 struct IfBool<true, TRUECASE, FALSECASE>
331 {
332  typedef TRUECASE type;
333 };
334 
335 template <class TRUECASE, class FALSECASE>
336 struct IfBool<false, TRUECASE, FALSECASE>
337 {
338  typedef FALSECASE type;
339 };
340 
341 template <class L, class R>
342 struct IsSameType
343 {
344  typedef VigraFalseType result; // deprecated
345  static const bool boolResult = false; // deprecated
346  typedef VigraFalseType type;
347  static const bool value = false;
348 };
349 
350 template <class T>
351 struct IsSameType<T, T>
352 {
353  typedef VigraTrueType result; // deprecated
354  static const bool boolResult = true; // deprecated
355  typedef VigraTrueType type;
356  static const bool value = true;
357 };
358 
359 template <class L, class R>
360 struct IsDifferentType
361 {
362  typedef VigraTrueType type;
363  static const bool value = true;
364 };
365 
366 template <class T>
367 struct IsDifferentType<T, T>
368 {
369  typedef VigraFalseType type;
370  static const bool value = false;
371 };
372 
373 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
374 
375 template <class From, class To>
376 struct IsConvertibleTo
377 {
378  typedef char falseResult[1];
379  typedef char trueResult[2];
380 
381  static From const & check();
382 
383  static falseResult * testIsConvertible(...);
384  static trueResult * testIsConvertible(To const &);
385 
386  enum { resultSize = sizeof(*testIsConvertible(check())) };
387 
388  static const bool value = (resultSize == 2);
389  typedef typename
390  IfBool<value, VigraTrueType, VigraFalseType>::type
391  type;
392 };
393 
394 template <class DERIVED, class BASE>
395 struct IsDerivedFrom
396 {
397  typedef char falseResult[1];
398  typedef char trueResult[2];
399 
400  static falseResult * testIsDerivedFrom(...);
401  static trueResult * testIsDerivedFrom(BASE const *);
402 
403  enum { resultSize = sizeof(*testIsDerivedFrom(static_cast<DERIVED const *>(0))) };
404 
405  static const bool value = (resultSize == 2);
406  typedef typename
407  IfBool<value, VigraTrueType, VigraFalseType>::type
408  type;
409 
410  static const bool boolResult = value; // deprecated
411  typedef type result; // deprecated
412 };
413 
414 template <class T>
415 struct UnqualifiedType
416 {
417  typedef T type;
418  static const bool isConst = false;
419  static const bool isReference = false;
420  static const bool isPointer = false;
421 };
422 
423 template <class T>
424 struct UnqualifiedType<T const>
425 {
426  typedef T type;
427  static const bool isConst = true;
428  static const bool isReference = false;
429  static const bool isPointer = false;
430 };
431 
432 template <class T>
433 struct UnqualifiedType<T &>
434 : public UnqualifiedType<T>
435 {
436  static const bool isReference = true;
437 };
438 
439 template <class T>
440 struct UnqualifiedType<T const &>
441 : public UnqualifiedType<T const>
442 {
443  static const bool isReference = true;
444 };
445 
446 template <class T>
447 struct UnqualifiedType<T *>
448 : public UnqualifiedType<T>
449 {
450  static const bool isPointer = true;
451 };
452 
453 template <class T>
454 struct UnqualifiedType<T const *>
455 : public UnqualifiedType<T const>
456 {
457  static const bool isPointer = true;
458 };
459 
460 template <bool, class T = void>
461 struct enable_if {};
462 template <class T>
463 struct enable_if<true, T> { typedef T type; };
464 
465 struct sfinae_void;
466 
467 template <class T, template<class> class USER>
468 struct sfinae_test
469 {
470  typedef char falseResult[1];
471  typedef char trueResult[2];
472 
473  static falseResult * test(...);
474  static trueResult * test(USER<sfinae_void>);
475 
476  enum { resultSize = sizeof(*test(static_cast<T*>(0))) };
477 
478  static const bool value = (resultSize == 2);
479  typedef typename
480  IfBool<value, VigraTrueType, VigraFalseType>::type
481  type;
482 };
483 
484 template <class T>
485 struct has_argument_type : public sfinae_test<T, has_argument_type>
486 {
487  template <class U> has_argument_type(U*, typename U::argument_type* = 0);
488 };
489 
490 template <class T>
491 struct has_result_type : public sfinae_test<T, has_result_type>
492 {
493  template <class U> has_result_type(U*, typename U::result_type* = 0);
494 };
495 
496 template <class T>
497 struct has_value_type : public sfinae_test<T, has_value_type>
498 {
499  template <class U> has_value_type(U*, typename U::value_type* = 0);
500 };
501 
502 template <class T>
503 struct IsIterator : public sfinae_test<T, IsIterator>
504 {
505  template <class U> IsIterator(U*, typename U::iterator_category* = 0);
506 };
507 
508 template <class T>
509 struct IsIterator<T*>
510 {
511  static const bool value = true;
512  typedef VigraTrueType type;
513 };
514 
515 template <class T>
516 struct IsIterator<T const *>
517 {
518  static const bool value = true;
519  typedef VigraTrueType type;
520 };
521 
522 template <class T>
523 struct has_real_promote_type : public sfinae_test<T, has_real_promote_type>
524 {
525  template <class U>
526  has_real_promote_type(U*, typename U::real_promote_type* = 0);
527 };
528 
529 template <class T, bool P = has_real_promote_type<T>::value>
530 struct get_optional_real_promote
531 {
532  typedef T type;
533 };
534 template <class T>
535 struct get_optional_real_promote<T, true>
536 {
537  typedef typename T::real_promote_type type;
538 };
539 
540 template <class T>
541 struct IsArray
542 {
543  typedef char falseResult[1];
544  typedef char trueResult[2];
545 
546  static falseResult * test(...);
547  template <class U, unsigned n>
548  static trueResult * test(U (*)[n]);
549 
550  enum { resultSize = sizeof(*test(static_cast<T*>(0))) };
551 
552  static const bool value = (resultSize == 2);
553  typedef typename
554  IfBool<value, VigraTrueType, VigraFalseType>::type
555  type;
556 };
557 
558 
559 template <class D, class B, class Z> inline
560 D & static_cast_2(Z & z)
561 {
562  return static_cast<D &>(static_cast<B &>(z));
563 }
564 
565 template <class A>
566 class copy_if_same_as
567 {
568  const bool copied;
569  const A *const data;
570  copy_if_same_as(const copy_if_same_as &);
571  void operator=(const copy_if_same_as &);
572 public:
573  copy_if_same_as(const A & x, const A & y)
574  : copied(&x == &y), data(copied ? new A(y) : &x) {}
575  ~copy_if_same_as()
576  {
577  if (copied)
578  delete data;
579  }
580  const A & operator()() const { return *data; }
581 };
582 
583 
584 template <class>
585 struct true_test : public VigraTrueType {};
586 
587 template <class>
588 struct false_test : VigraFalseType {};
589 
590 template <class PC, class T, class F>
591 struct ChooseBool
592 {
593  static const bool value = IfBool<PC::value, T, F>::type::value;
594 };
595 
596 template <bool>
597 struct choose_type
598 {
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; }
603 };
604 template <>
605 struct choose_type<false>
606 {
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; }
611 };
612 
613 template <class X>
614 struct HasMetaLog2
615 {
616  static const bool value = !std::numeric_limits<X>::is_signed
617  && std::numeric_limits<X>::is_integer;
618 };
619 template <class X>
620 struct EnableMetaLog2
621  : public enable_if<HasMetaLog2<X>::value> {};
622 template <class>
623 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
624 
625 // use a conforming template depth here (below 15 for up to 128 bits)
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>
629 class MetaLog2
630  : public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
631 {};
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>
634 {
635  static const unsigned value
636  = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
637 };
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>
640 {
641  static const unsigned value
642  = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
643 };
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>
646 {
647  static const unsigned value = 2;
648 };
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>
651 {
652  static const unsigned value = 1;
653 };
654 template <class X, X z, X u>
655 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
656 {
657  // A value of zero for MetaLog2<X, 0> is likely to cause most harm,
658  // such as division by zero or zero array sizes, this is actually indended.
659  static const unsigned value = 0;
660 };
661 
662 template <int X, unsigned int N>
663 struct MetaPow
664 {
665  static const long long value = MetaPow<X, N-1>::value * X;
666 };
667 
668 template <int X>
669 struct MetaPow<X, 0>
670 {
671  static const long long value = 1;
672 };
673 
674 /****************************************************************************/
675 /* */
676 /* TypeList and its functions */
677 /* */
678 /****************************************************************************/
679 
680 template<class HEAD, class TAIL=void>
681 struct TypeList
682 {
683  typedef TypeList<HEAD, TAIL> type;
684  typedef HEAD Head;
685  typedef TAIL Tail;
686 };
687 
688 template <class List, class T>
689 struct Contains;
690 
691 template <class Head, class Tail, class T>
692 struct Contains<TypeList<Head, Tail>, T>
693 {
694  typedef typename Contains<Tail, T>::type type;
695 };
696 
697 template <class Head, class Tail>
698 struct Contains<TypeList<Head, Tail>, Head>
699 {
700  typedef VigraTrueType type;
701 };
702 
703 template <class T>
704 struct Contains<void, T>
705 {
706  typedef VigraFalseType type;
707 };
708 
709 template <class List, class T>
710 struct Remove;
711 
712 template <class Head, class Tail, class T>
713 struct Remove<TypeList<Head, Tail>, T>
714 {
715  typedef TypeList<Head, typename Remove<Tail, T>::type> type;
716 };
717 
718 template <class Head, class Tail>
719 struct Remove<TypeList<Head, Tail>, Head>
720 {
721  typedef Tail type;
722 };
723 
724 template <class T>
725 struct Remove<void, T>
726 {
727  typedef void type;
728 };
729 
730 template <class A, class Tail=void>
731 struct Push
732 {
733  typedef TypeList<A, typename Tail::type> type;
734 };
735 
736 template <class Head, class Tail, class List>
737 struct Push<TypeList<Head, Tail>, List>
738 {
739  typedef typename Push<Tail, List>::type Rest;
740  typedef TypeList<Head, Rest> type;
741 };
742 
743 template <class Head, class Tail>
744 struct Push<TypeList<Head, Tail>, void>
745 {
746  typedef TypeList<Head, Tail> type;
747 };
748 
749 template <class A>
750 struct Push<A, void>
751 {
752  typedef TypeList<A> type;
753 };
754 
755 template <class A>
756 struct Push<void, A>
757 {
758  typedef A type;
759 };
760 
761 template <>
762 struct Push<void, void>
763 {
764  typedef void type;
765 };
766 
767 template <class A, class Tail=void>
768 struct PushUnique
769 {
770  typedef typename Contains<Tail, A>::type AlreadyInList;
771  typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
772 };
773 
774 template <class Head, class Tail, class List>
775 struct PushUnique<TypeList<Head, Tail>, List>
776 {
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;
780 };
781 
782 template <class Head, class Tail>
783 struct PushUnique<TypeList<Head, Tail>, void>
784 {
785  typedef TypeList<Head, Tail> type;
786 };
787 
788 template <class A>
789 struct PushUnique<A, void>
790 {
791  typedef TypeList<A> type;
792 };
793 
794 template <class A>
795 struct PushUnique<void, A>
796 {
797  typedef A type;
798 };
799 
800 template <>
801 struct PushUnique<void, void>
802 {
803  typedef void type;
804 };
805 
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>
810 struct MakeTypeList
811 {
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;
831  typedef L01 type;
832 };
833 
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
839 {
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;
859  typedef L01 type;
860 };
861 
862 // mask cl.exe shortcomings [end]
863 #if defined(_MSC_VER)
864 #pragma warning( pop )
865 #endif
866 
867 } // namespace vigra
868 
869 #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.10.0 (Thu Jan 8 2015)