[ 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 #ifdef __APPLE__
53 #include <AssertMacros.h>
54 #undef check
55 #endif
56 
57 template <int N>
58 class MetaInt
59 {
60  public:
61  static const int value = N;
62 };
63 
64 template <int N1, int N2>
65 class MetaMax
66 {
67  public:
68  static const int value = N1 < N2 ? N2 : N1;
69 };
70 
71 template <int N1, int N2>
72 class MetaMin
73 {
74  public:
75  static const int value = N1 < N2 ? N1 : N2;
76 };
77 
78 struct VigraTrueType
79 {
80  static const bool asBool = true, value = true;
81 };
82 
83 struct VigraFalseType
84 {
85  static const bool asBool = false, value = false;
86 };
87 
88 /** \addtogroup MultiArrayTags Multi-dimensional Array Tags
89 
90  Meta-programming tags to mark array's as strided, unstrided, or chunked.
91 
92  An array is unstrided if the array elements occupy consecutive
93  memory locations, strided if adjacent elements have a constant
94  offset (e.g. when a view skips every other array element),
95  and chunked if the array is stored in rectangular blocks with
96  arbitrary offsets inbetween.
97 
98  These tags are used to specialize algorithms for different memory
99  layouts. Older compilers can generate faster code for unstrided arrays.
100  Normally, users don't have to worry about these tags.
101 */
102 
103 //@{
104 
105 /********************************************************/
106 /* */
107 /* tags for MultiArray memory layout */
108 /* */
109 /********************************************************/
110 
111 /** tag for marking a MultiArray strided.
112 
113  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
114  Namespace: vigra
115 */
116 struct StridedArrayTag {};
117 
118 /** tag for marking a MultiArray unstrided.
119 
120  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
121  Namespace: vigra
122 */
124 
125 /** tag for marking a MultiArray chunked.
126 
127  <b>\#include</b> <vigra/metaprogramming.hxx> <br/>
128  Namespace: vigra
129 */
130 struct ChunkedArrayTag {};
131 
132 /********************************************************/
133 /* */
134 /* TypeTraits */
135 /* */
136 /********************************************************/
137 
138 template<class T>
139 class TypeTraits
140 {
141  public:
142  typedef VigraFalseType isConst;
143  typedef VigraFalseType isPOD;
144  typedef VigraFalseType isBuiltinType;
145 };
146 
147 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
148 
149 template<class T>
150 class TypeTraits<T const>
151 : public TypeTraits<T>
152 {
153  public:
154  typedef VigraTrueType isConst;
155 };
156 
157 template<class T>
158 class TypeTraits<T *>
159 {
160  public:
161  typedef VigraFalseType isConst;
162  typedef VigraTrueType isPOD;
163  typedef VigraTrueType isBuiltinType;
164 };
165 
166 template<class T>
167 class TypeTraits<T const *>
168 {
169  public:
170  typedef VigraFalseType isConst;
171  typedef VigraTrueType isPOD;
172  typedef VigraTrueType isBuiltinType;
173 };
174 
175 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
176 
177 namespace detail {
178 
179 template <int size>
180 struct SizeToType;
181 
182 } // namespace detail
183 
184 #define VIGRA_TYPE_TRAITS(type, size) \
185 template<> \
186 class TypeTraits<type> \
187 { \
188  public: \
189  typedef VigraFalseType isConst; \
190  typedef VigraTrueType isPOD; \
191  typedef VigraTrueType isBuiltinType; \
192  typedef char TypeToSize[size]; \
193 }; \
194  \
195 namespace detail { \
196  TypeTraits<type>::TypeToSize * typeToSize(type); \
197  \
198  template <> \
199  struct SizeToType<size> \
200  { \
201  typedef type result; \
202  }; \
203 }
204 
205 VIGRA_TYPE_TRAITS(char, 1)
206 VIGRA_TYPE_TRAITS(signed char, 2)
207 VIGRA_TYPE_TRAITS(unsigned char, 3)
208 VIGRA_TYPE_TRAITS(short, 4)
209 VIGRA_TYPE_TRAITS(unsigned short, 5)
210 VIGRA_TYPE_TRAITS(int, 6)
211 VIGRA_TYPE_TRAITS(unsigned int, 7)
212 VIGRA_TYPE_TRAITS(long, 8)
213 VIGRA_TYPE_TRAITS(unsigned long, 9)
214 VIGRA_TYPE_TRAITS(float, 10)
215 VIGRA_TYPE_TRAITS(double, 11)
216 VIGRA_TYPE_TRAITS(long double, 12)
217 #ifdef LLONG_MAX
218 VIGRA_TYPE_TRAITS(long long, 13)
219 VIGRA_TYPE_TRAITS(unsigned long long, 14)
220 #endif
221 
222 #undef VIGRA_TYPE_TRAITS
223 
224 //@}
225 
226 template <class A>
227 struct Not;
228 
229 template <>
230 struct Not<VigraTrueType>
231 {
232  typedef VigraFalseType result; // deprecated
233  static const bool boolResult = false; // deprecated
234  typedef VigraFalseType type;
235  static const bool value = false;
236 };
237 
238 template <>
239 struct Not<VigraFalseType>
240 {
241  typedef VigraTrueType result; // deprecated
242  static const bool boolResult = true; // deprecated
243  typedef VigraTrueType type;
244  static const bool value = true;
245 };
246 
247 template <class L, class R>
248 struct And;
249 
250 template <>
251 struct And<VigraFalseType, VigraFalseType>
252 {
253  typedef VigraFalseType result; // deprecated
254  static const bool boolResult = false; // deprecated
255  typedef VigraFalseType type;
256  static const bool value = false;
257 };
258 
259 template <>
260 struct And<VigraFalseType, VigraTrueType>
261 {
262  typedef VigraFalseType result; // deprecated
263  static const bool boolResult = false; // deprecated
264  typedef VigraFalseType type;
265  static const bool value = false;
266 };
267 
268 template <>
269 struct And<VigraTrueType, VigraFalseType>
270 {
271  typedef VigraFalseType result; // deprecated
272  static const bool boolResult = false; // deprecated
273  typedef VigraFalseType type;
274  static const bool value = false;
275 };
276 
277 template <>
278 struct And<VigraTrueType, VigraTrueType>
279 {
280  typedef VigraTrueType result; // deprecated
281  static const bool boolResult = true; // deprecated
282  typedef VigraTrueType type;
283  static const bool value = true;
284 };
285 
286 template <class L, class R>
287 struct Or;
288 
289 template <>
290 struct Or<VigraFalseType, VigraFalseType>
291 {
292  typedef VigraFalseType result; // deprecated
293  static const bool boolResult = false; // deprecated
294  typedef VigraFalseType type;
295  static const bool value = false;
296 };
297 
298 template <>
299 struct Or<VigraTrueType, VigraFalseType>
300 {
301  typedef VigraTrueType result; // deprecated
302  static const bool boolResult = true; // deprecated
303  typedef VigraTrueType type;
304  static const bool value = true;
305 };
306 
307 template <>
308 struct Or<VigraFalseType, VigraTrueType>
309 {
310  typedef VigraTrueType result; // deprecated
311  static const bool boolResult = true; // deprecated
312  typedef VigraTrueType type;
313  static const bool value = true;
314 };
315 
316 template <>
317 struct Or<VigraTrueType, VigraTrueType>
318 {
319  typedef VigraTrueType result; // deprecated
320  static const bool boolResult = true; // deprecated
321  typedef VigraTrueType type;
322  static const bool value = true;
323 };
324 
325 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
326 
327 template <class PREDICATE, class TRUECASE, class FALSECASE>
328 struct If;
329 
330 template <class TRUECASE, class FALSECASE>
331 struct If<VigraTrueType, TRUECASE, FALSECASE>
332 {
333  typedef TRUECASE type;
334 };
335 
336 template <class TRUECASE, class FALSECASE>
337 struct If<VigraFalseType, TRUECASE, FALSECASE>
338 {
339  typedef FALSECASE type;
340 };
341 
342 template <bool PREDICATE, class TRUECASE, class FALSECASE>
343 struct IfBool;
344 
345 template <class TRUECASE, class FALSECASE>
346 struct IfBool<true, TRUECASE, FALSECASE>
347 {
348  typedef TRUECASE type;
349 };
350 
351 template <class TRUECASE, class FALSECASE>
352 struct IfBool<false, TRUECASE, FALSECASE>
353 {
354  typedef FALSECASE type;
355 };
356 
357 template <class L, class R>
358 struct IsSameType
359 {
360  typedef VigraFalseType result; // deprecated
361  static const bool boolResult = false; // deprecated
362  typedef VigraFalseType type;
363  static const bool value = false;
364 };
365 
366 template <class T>
367 struct IsSameType<T, T>
368 {
369  typedef VigraTrueType result; // deprecated
370  static const bool boolResult = true; // deprecated
371  typedef VigraTrueType type;
372  static const bool value = true;
373 };
374 
375 template <class L, class R>
376 struct IsDifferentType
377 {
378  typedef VigraTrueType type;
379  static const bool value = true;
380 };
381 
382 template <class T>
383 struct IsDifferentType<T, T>
384 {
385  typedef VigraFalseType type;
386  static const bool value = false;
387 };
388 
389 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
390 
391 template <class From, class To>
392 struct IsConvertibleTo
393 {
394  typedef char falseResult[1];
395  typedef char trueResult[2];
396 
397  static From const & check();
398 
399  static falseResult * testIsConvertible(...);
400  static trueResult * testIsConvertible(To const &);
401 
402  enum { resultSize = sizeof(*testIsConvertible(check())) };
403 
404  static const bool value = (resultSize == 2);
405  typedef typename
406  IfBool<value, VigraTrueType, VigraFalseType>::type
407  type;
408 };
409 
410 template <class DERIVED, class BASE>
411 struct IsDerivedFrom
412 {
413  typedef char falseResult[1];
414  typedef char trueResult[2];
415 
416  static falseResult * testIsDerivedFrom(...);
417  static trueResult * testIsDerivedFrom(BASE const *);
418 
419  enum { resultSize = sizeof(*testIsDerivedFrom(static_cast<DERIVED const *>(0))) };
420 
421  static const bool value = (resultSize == 2);
422  typedef typename
423  IfBool<value, VigraTrueType, VigraFalseType>::type
424  type;
425 
426  static const bool boolResult = value; // deprecated
427  typedef type result; // deprecated
428 };
429 
430 template <class T>
431 struct UnqualifiedType
432 {
433  typedef T type;
434  static const bool isConst = false;
435  static const bool isReference = false;
436  static const bool isPointer = false;
437 };
438 
439 template <class T>
440 struct UnqualifiedType<T const>
441 {
442  typedef T type;
443  static const bool isConst = true;
444  static const bool isReference = false;
445  static const bool isPointer = false;
446 };
447 
448 template <class T>
449 struct UnqualifiedType<T &>
450 : public UnqualifiedType<T>
451 {
452  static const bool isReference = true;
453 };
454 
455 template <class T>
456 struct UnqualifiedType<T const &>
457 : public UnqualifiedType<T const>
458 {
459  static const bool isReference = true;
460 };
461 
462 template <class T>
463 struct UnqualifiedType<T *>
464 : public UnqualifiedType<T>
465 {
466  static const bool isPointer = true;
467 };
468 
469 template <class T>
470 struct UnqualifiedType<T const *>
471 : public UnqualifiedType<T const>
472 {
473  static const bool isPointer = true;
474 };
475 
476 template <bool, class T = void>
477 struct enable_if {};
478 template <class T>
479 struct enable_if<true, T> { typedef T type; };
480 
481 struct sfinae_void;
482 
483 template <class T, template<class> class USER>
484 struct sfinae_test
485 {
486  typedef char falseResult[1];
487  typedef char trueResult[2];
488 
489  static falseResult * test(...);
490  static trueResult * test(USER<sfinae_void>);
491 
492  enum { resultSize = sizeof(*test(static_cast<T*>(0))) };
493 
494  static const bool value = (resultSize == 2);
495  typedef typename
496  IfBool<value, VigraTrueType, VigraFalseType>::type
497  type;
498 };
499 
500 template <class T>
501 struct has_argument_type : public sfinae_test<T, has_argument_type>
502 {
503  template <class U> has_argument_type(U*, typename U::argument_type* = 0);
504 };
505 
506 template <class T>
507 struct has_result_type : public sfinae_test<T, has_result_type>
508 {
509  template <class U> has_result_type(U*, typename U::result_type* = 0);
510 };
511 
512 template <class T>
513 struct has_value_type : public sfinae_test<T, has_value_type>
514 {
515  template <class U> has_value_type(U*, typename U::value_type* = 0);
516 };
517 
518 template <class T>
519 struct IsIterator : public sfinae_test<T, IsIterator>
520 {
521  template <class U> IsIterator(U*, typename U::iterator_category* = 0);
522 };
523 
524 template <class T>
525 struct IsIterator<T*>
526 {
527  static const bool value = true;
528  typedef VigraTrueType type;
529 };
530 
531 template <class T>
532 struct IsIterator<T const *>
533 {
534  static const bool value = true;
535  typedef VigraTrueType type;
536 };
537 
538 template <class T>
539 struct has_real_promote_type : public sfinae_test<T, has_real_promote_type>
540 {
541  template <class U>
542  has_real_promote_type(U*, typename U::real_promote_type* = 0);
543 };
544 
545 template <class T, bool P = has_real_promote_type<T>::value>
546 struct get_optional_real_promote
547 {
548  typedef T type;
549 };
550 template <class T>
551 struct get_optional_real_promote<T, true>
552 {
553  typedef typename T::real_promote_type type;
554 };
555 
556 template <class T>
557 struct IsArray
558 {
559  typedef char falseResult[1];
560  typedef char trueResult[2];
561 
562  static falseResult * test(...);
563  template <class U, unsigned n>
564  static trueResult * test(U (*)[n]);
565 
566  enum { resultSize = sizeof(*test(static_cast<T*>(0))) };
567 
568  static const bool value = (resultSize == 2);
569  typedef typename
570  IfBool<value, VigraTrueType, VigraFalseType>::type
571  type;
572 };
573 
574 
575 template <class D, class B, class Z> inline
576 D & static_cast_2(Z & z)
577 {
578  return static_cast<D &>(static_cast<B &>(z));
579 }
580 
581 template <class A>
582 class copy_if_same_as
583 {
584  const bool copied;
585  const A *const data;
586  copy_if_same_as(const copy_if_same_as &);
587  void operator=(const copy_if_same_as &);
588 public:
589  copy_if_same_as(const A & x, const A & y)
590  : copied(&x == &y), data(copied ? new A(y) : &x) {}
591  ~copy_if_same_as()
592  {
593  if (copied)
594  delete data;
595  }
596  const A & operator()() const { return *data; }
597 };
598 
599 
600 template <class>
601 struct true_test : public VigraTrueType {};
602 
603 template <class>
604 struct false_test : VigraFalseType {};
605 
606 template <class PC, class T, class F>
607 struct ChooseBool
608 {
609  static const bool value = IfBool<PC::value, T, F>::type::value;
610 };
611 
612 template <bool>
613 struct choose_type
614 {
615  template <class A, class B>
616  static const A & at(const A & a, const B &) { return a; }
617  template <class A, class B>
618  static A & at( A & a, B &) { return a; }
619 };
620 template <>
621 struct choose_type<false>
622 {
623  template <class A, class B>
624  static const B & at(const A &, const B & b) { return b; }
625  template <class A, class B>
626  static B & at( A &, B & b) { return b; }
627 };
628 
629 template <class X>
630 struct HasMetaLog2
631 {
632  static const bool value = !std::numeric_limits<X>::is_signed
633  && std::numeric_limits<X>::is_integer;
634 };
635 template <class X>
636 struct EnableMetaLog2
637  : public enable_if<HasMetaLog2<X>::value> {};
638 template <class>
639 class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
640 
641 // use a conforming template depth here (below 15 for up to 128 bits)
642 template <class X = unsigned long,
643  X n = ~(X(0)), unsigned s = 1, unsigned t = 0, bool q = 1,
644  X m = 0, X z = 0, X u = 1, class = void>
645 class MetaLog2
646  : public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
647 {};
648 template <class X, X n, unsigned s, unsigned t, bool q, X m, X z, X u>
649 struct MetaLog2 <X, n, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
650 {
651  static const unsigned value
652  = t + MetaLog2<X, (n >> s), s * (1 + q), s, !q, n / 2, z, u>::value;
653 };
654 template <class X, unsigned s, unsigned t, bool q, X m, X z, X u>
655 struct MetaLog2<X, z, s, t, q, m, z, u, typename EnableMetaLog2<X>::type>
656 {
657  static const unsigned value
658  = 1 + MetaLog2<X, m / 2, 2, 1, 1, 0, z, u>::value;
659 };
660 template <class X, unsigned s, unsigned t, bool q, X z, X u>
661 struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
662 {
663  static const unsigned value = 2;
664 };
665 template <class X, unsigned s, unsigned t, bool q, X z, X u>
666 struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
667 {
668  static const unsigned value = 1;
669 };
670 template <class X, X z, X u>
671 struct MetaLog2<X, z, 1, 0, 1, z, z, u, typename EnableMetaLog2<X>::type>
672 {
673  // A value of zero for MetaLog2<X, 0> is likely to cause most harm,
674  // such as division by zero or zero array sizes, this is actually indended.
675  static const unsigned value = 0;
676 };
677 
678 template <int X, unsigned int N>
679 struct MetaPow
680 {
681  static const long long value = MetaPow<X, N-1>::value * X;
682 };
683 
684 template <int X>
685 struct MetaPow<X, 0>
686 {
687  static const long long value = 1;
688 };
689 
690 /****************************************************************************/
691 /* */
692 /* TypeList and its functions */
693 /* */
694 /****************************************************************************/
695 
696 template<class HEAD, class TAIL=void>
697 struct TypeList
698 {
699  typedef TypeList<HEAD, TAIL> type;
700  typedef HEAD Head;
701  typedef TAIL Tail;
702 };
703 
704 template <class List, class T>
705 struct Contains;
706 
707 template <class Head, class Tail, class T>
708 struct Contains<TypeList<Head, Tail>, T>
709 {
710  typedef typename Contains<Tail, T>::type type;
711 };
712 
713 template <class Head, class Tail>
714 struct Contains<TypeList<Head, Tail>, Head>
715 {
716  typedef VigraTrueType type;
717 };
718 
719 template <class T>
720 struct Contains<void, T>
721 {
722  typedef VigraFalseType type;
723 };
724 
725 template <class List, class T>
726 struct Remove;
727 
728 template <class Head, class Tail, class T>
729 struct Remove<TypeList<Head, Tail>, T>
730 {
731  typedef TypeList<Head, typename Remove<Tail, T>::type> type;
732 };
733 
734 template <class Head, class Tail>
735 struct Remove<TypeList<Head, Tail>, Head>
736 {
737  typedef Tail type;
738 };
739 
740 template <class T>
741 struct Remove<void, T>
742 {
743  typedef void type;
744 };
745 
746 template <class A, class Tail=void>
747 struct Push
748 {
749  typedef TypeList<A, typename Tail::type> type;
750 };
751 
752 template <class Head, class Tail, class List>
753 struct Push<TypeList<Head, Tail>, List>
754 {
755  typedef typename Push<Tail, List>::type Rest;
756  typedef TypeList<Head, Rest> type;
757 };
758 
759 template <class Head, class Tail>
760 struct Push<TypeList<Head, Tail>, void>
761 {
762  typedef TypeList<Head, Tail> type;
763 };
764 
765 template <class A>
766 struct Push<A, void>
767 {
768  typedef TypeList<A> type;
769 };
770 
771 template <class A>
772 struct Push<void, A>
773 {
774  typedef A type;
775 };
776 
777 template <>
778 struct Push<void, void>
779 {
780  typedef void type;
781 };
782 
783 template <class A, class Tail=void>
784 struct PushUnique
785 {
786  typedef typename Contains<Tail, A>::type AlreadyInList;
787  typedef typename If<AlreadyInList, typename Tail::type, TypeList<A, typename Tail::type> >::type type;
788 };
789 
790 template <class Head, class Tail, class List>
791 struct PushUnique<TypeList<Head, Tail>, List>
792 {
793  typedef typename PushUnique<Tail, List>::type Rest;
794  typedef typename Contains<Rest, Head>::type HeadAlreadyInList;
795  typedef typename If<HeadAlreadyInList, Rest, TypeList<Head, Rest> >::type type;
796 };
797 
798 template <class Head, class Tail>
799 struct PushUnique<TypeList<Head, Tail>, void>
800 {
801  typedef TypeList<Head, Tail> type;
802 };
803 
804 template <class A>
805 struct PushUnique<A, void>
806 {
807  typedef TypeList<A> type;
808 };
809 
810 template <class A>
811 struct PushUnique<void, A>
812 {
813  typedef A type;
814 };
815 
816 template <>
817 struct PushUnique<void, void>
818 {
819  typedef void type;
820 };
821 
822 template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
823  class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
824  class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
825  class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
826 struct MakeTypeList
827 {
828  typedef typename Push<T19, T20>::type L19;
829  typedef typename Push<T18, L19>::type L18;
830  typedef typename Push<T17, L18>::type L17;
831  typedef typename Push<T16, L17>::type L16;
832  typedef typename Push<T15, L16>::type L15;
833  typedef typename Push<T14, L15>::type L14;
834  typedef typename Push<T13, L14>::type L13;
835  typedef typename Push<T12, L13>::type L12;
836  typedef typename Push<T11, L12>::type L11;
837  typedef typename Push<T10, L11>::type L10;
838  typedef typename Push<T09, L10>::type L09;
839  typedef typename Push<T08, L09>::type L08;
840  typedef typename Push<T07, L08>::type L07;
841  typedef typename Push<T06, L07>::type L06;
842  typedef typename Push<T05, L06>::type L05;
843  typedef typename Push<T04, L05>::type L04;
844  typedef typename Push<T03, L04>::type L03;
845  typedef typename Push<T02, L03>::type L02;
846  typedef typename Push<T01, L02>::type L01;
847  typedef L01 type;
848 };
849 
850 template <class T01=void, class T02=void, class T03=void, class T04=void, class T05=void,
851  class T06=void, class T07=void, class T08=void, class T09=void, class T10=void,
852  class T11=void, class T12=void, class T13=void, class T14=void, class T15=void,
853  class T16=void, class T17=void, class T18=void, class T19=void, class T20=void>
854 struct MakeTypeListUnique
855 {
856  typedef typename PushUnique<T19, T20>::type L19;
857  typedef typename PushUnique<T18, L19>::type L18;
858  typedef typename PushUnique<T17, L18>::type L17;
859  typedef typename PushUnique<T16, L17>::type L16;
860  typedef typename PushUnique<T15, L16>::type L15;
861  typedef typename PushUnique<T14, L15>::type L14;
862  typedef typename PushUnique<T13, L14>::type L13;
863  typedef typename PushUnique<T12, L13>::type L12;
864  typedef typename PushUnique<T11, L12>::type L11;
865  typedef typename PushUnique<T10, L11>::type L10;
866  typedef typename PushUnique<T09, L10>::type L09;
867  typedef typename PushUnique<T08, L09>::type L08;
868  typedef typename PushUnique<T07, L08>::type L07;
869  typedef typename PushUnique<T06, L07>::type L06;
870  typedef typename PushUnique<T05, L06>::type L05;
871  typedef typename PushUnique<T04, L05>::type L04;
872  typedef typename PushUnique<T03, L04>::type L03;
873  typedef typename PushUnique<T02, L03>::type L02;
874  typedef typename PushUnique<T01, L02>::type L01;
875  typedef L01 type;
876 };
877 
878 template <typename T0>
879 inline void ignore_argument(const T0 &)
880 {}
881 
882 template <typename T0, typename T1>
883 inline void ignore_argument(const T0 &, const T1 &)
884 {}
885 
886 template <typename T0, typename T1, typename T2>
887 inline void ignore_argument(const T0 &, const T1 &, const T2 &)
888 {}
889 
890 template <typename T0, typename T1, typename T2, typename T3>
891 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &)
892 {}
893 
894 template <typename T0, typename T1, typename T2, typename T3, typename T4>
895 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &)
896 {}
897 
898 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
899 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &)
900 {}
901 
902 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
903 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &)
904 {}
905 
906 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
907 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &)
908 {}
909 
910 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
911 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &, const T8 &)
912 {}
913 
914 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
915 inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &, const T8 &, const T9 &)
916 {}
917 
918 // mask cl.exe shortcomings [end]
919 #if defined(_MSC_VER)
920 #pragma warning( pop )
921 #endif
922 
923 } // namespace vigra
924 
925 #endif /* VIGRA_METAPROGRAMMING_HXX */
Definition: metaprogramming.hxx:116
Definition: metaprogramming.hxx:123
Definition: metaprogramming.hxx:130

© 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.11.1 (Fri May 19 2017)