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

metaprogramming.hxx |

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 */
123 struct UnstridedArrayTag {};
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 */
vigra::StridedArrayTag
Definition: metaprogramming.hxx:116
vigra::UnstridedArrayTag
Definition: metaprogramming.hxx:123
vigra::ChunkedArrayTag
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)