[ 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
44namespace 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
57template <int N>
58class MetaInt
59{
60 public:
61 static const int value = N;
62};
63
64template <int N1, int N2>
65class MetaMax
66{
67 public:
68 static const int value = N1 < N2 ? N2 : N1;
69};
70
71template <int N1, int N2>
72class MetaMin
73{
74 public:
75 static const int value = N1 < N2 ? N1 : N2;
76};
77
78struct VigraTrueType
79{
80 static const bool asBool = true, value = true;
81};
82
83struct 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*/
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*/
131
132/********************************************************/
133/* */
134/* TypeTraits */
135/* */
136/********************************************************/
137
138template<class T>
139class 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
149template<class T>
150class TypeTraits<T const>
151: public TypeTraits<T>
152{
153 public:
154 typedef VigraTrueType isConst;
155};
156
157template<class T>
158class TypeTraits<T *>
159{
160 public:
161 typedef VigraFalseType isConst;
162 typedef VigraTrueType isPOD;
163 typedef VigraTrueType isBuiltinType;
164};
165
166template<class T>
167class 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
177namespace detail {
178
179template <int size>
180struct SizeToType;
181
182} // namespace detail
183
184#define VIGRA_TYPE_TRAITS(type, size) \
185template<> \
186class TypeTraits<type> \
187{ \
188 public: \
189 typedef VigraFalseType isConst; \
190 typedef VigraTrueType isPOD; \
191 typedef VigraTrueType isBuiltinType; \
192 typedef char TypeToSize[size]; \
193}; \
194 \
195namespace detail { \
196 TypeTraits<type>::TypeToSize * typeToSize(type); \
197 \
198 template <> \
199 struct SizeToType<size> \
200 { \
201 typedef type result; \
202 }; \
203}
204
205VIGRA_TYPE_TRAITS(char, 1)
206VIGRA_TYPE_TRAITS(signed char, 2)
207VIGRA_TYPE_TRAITS(unsigned char, 3)
208VIGRA_TYPE_TRAITS(short, 4)
209VIGRA_TYPE_TRAITS(unsigned short, 5)
210VIGRA_TYPE_TRAITS(int, 6)
211VIGRA_TYPE_TRAITS(unsigned int, 7)
212VIGRA_TYPE_TRAITS(long, 8)
213VIGRA_TYPE_TRAITS(unsigned long, 9)
214VIGRA_TYPE_TRAITS(float, 10)
215VIGRA_TYPE_TRAITS(double, 11)
216VIGRA_TYPE_TRAITS(long double, 12)
217#ifdef LLONG_MAX
218VIGRA_TYPE_TRAITS(long long, 13)
219VIGRA_TYPE_TRAITS(unsigned long long, 14)
220#endif
221
222#undef VIGRA_TYPE_TRAITS
223
224//@}
225
226template <class A>
227struct Not;
228
229template <>
230struct 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
238template <>
239struct 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
247template <class L, class R>
248struct And;
249
250template <>
251struct 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
259template <>
260struct 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
268template <>
269struct 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
277template <>
278struct 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
286template <class L, class R>
287struct Or;
288
289template <>
290struct 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
298template <>
299struct 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
307template <>
308struct 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
316template <>
317struct 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
327template <class PREDICATE, class TRUECASE, class FALSECASE>
328struct If;
329
330template <class TRUECASE, class FALSECASE>
331struct If<VigraTrueType, TRUECASE, FALSECASE>
332{
333 typedef TRUECASE type;
334};
335
336template <class TRUECASE, class FALSECASE>
337struct If<VigraFalseType, TRUECASE, FALSECASE>
338{
339 typedef FALSECASE type;
340};
341
342template <bool PREDICATE, class TRUECASE, class FALSECASE>
343struct IfBool;
344
345template <class TRUECASE, class FALSECASE>
346struct IfBool<true, TRUECASE, FALSECASE>
347{
348 typedef TRUECASE type;
349};
350
351template <class TRUECASE, class FALSECASE>
352struct IfBool<false, TRUECASE, FALSECASE>
353{
354 typedef FALSECASE type;
355};
356
357template <class L, class R>
358struct 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
366template <class T>
367struct 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
375template <class L, class R>
376struct IsDifferentType
377{
378 typedef VigraTrueType type;
379 static const bool value = true;
380};
381
382template <class T>
383struct IsDifferentType<T, T>
384{
385 typedef VigraFalseType type;
386 static const bool value = false;
387};
388
389#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
390
391template <class From, class To>
392struct 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
410template <class DERIVED, class BASE>
411struct 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
430template <class T>
431struct 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
439template <class T>
440struct 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
448template <class T>
449struct UnqualifiedType<T &>
450: public UnqualifiedType<T>
451{
452 static const bool isReference = true;
453};
454
455template <class T>
456struct UnqualifiedType<T const &>
457: public UnqualifiedType<T const>
458{
459 static const bool isReference = true;
460};
461
462template <class T>
463struct UnqualifiedType<T *>
464: public UnqualifiedType<T>
465{
466 static const bool isPointer = true;
467};
468
469template <class T>
470struct UnqualifiedType<T const *>
471: public UnqualifiedType<T const>
472{
473 static const bool isPointer = true;
474};
475
476template <bool, class T = void>
477struct enable_if {};
478template <class T>
479struct enable_if<true, T> { typedef T type; };
480
481struct sfinae_void;
482
483template <class T, template<class> class USER>
484struct 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
500template <class T>
501struct 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
506template <class T>
507struct 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
512template <class T>
513struct 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
518template <class T>
519struct IsIterator : public sfinae_test<T, IsIterator>
520{
521 template <class U> IsIterator(U*, typename U::iterator_category* = 0);
522};
523
524template <class T>
525struct IsIterator<T*>
526{
527 static const bool value = true;
528 typedef VigraTrueType type;
529};
530
531template <class T>
532struct IsIterator<T const *>
533{
534 static const bool value = true;
535 typedef VigraTrueType type;
536};
537
538template <class T>
539struct 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
545template <class T, bool P = has_real_promote_type<T>::value>
546struct get_optional_real_promote
547{
548 typedef T type;
549};
550template <class T>
551struct get_optional_real_promote<T, true>
552{
553 typedef typename T::real_promote_type type;
554};
555
556template <class T>
557struct 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
575template <class D, class B, class Z> inline
576D & static_cast_2(Z & z)
577{
578 return static_cast<D &>(static_cast<B &>(z));
579}
580
581template <class A>
582class 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 &);
588public:
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
600template <class>
601struct true_test : public VigraTrueType {};
602
603template <class>
604struct false_test : VigraFalseType {};
605
606template <class PC, class T, class F>
607struct ChooseBool
608{
609 static const bool value = IfBool<PC::value, T, F>::type::value;
610};
611
612template <bool>
613struct 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};
620template <>
621struct 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
629template <class X>
630struct HasMetaLog2
631{
632 static const bool value = !std::numeric_limits<X>::is_signed
633 && std::numeric_limits<X>::is_integer;
634};
635template <class X>
636struct EnableMetaLog2
637 : public enable_if<HasMetaLog2<X>::value> {};
638template <class>
639class vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_;
640
641// use a conforming template depth here (below 15 for up to 128 bits)
642template <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>
645class MetaLog2
646 : public vigra_error_MetaLog2_accepts_only_unsigned_types_and_no_<X>
647{};
648template <class X, X n, unsigned s, unsigned t, bool q, X m, X z, X u>
649struct 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};
654template <class X, unsigned s, unsigned t, bool q, X m, X z, X u>
655struct 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};
660template <class X, unsigned s, unsigned t, bool q, X z, X u>
661struct MetaLog2<X, z, s, t, q, u, z, u, typename EnableMetaLog2<X>::type>
662{
663 static const unsigned value = 2;
664};
665template <class X, unsigned s, unsigned t, bool q, X z, X u>
666struct MetaLog2<X, z, s, t, q, z, z, u, typename EnableMetaLog2<X>::type>
667{
668 static const unsigned value = 1;
669};
670template <class X, X z, X u>
671struct 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
678template <int X, unsigned int N>
679struct MetaPow
680{
681 static const long long value = MetaPow<X, N-1>::value * X;
682};
683
684template <int X>
685struct MetaPow<X, 0>
686{
687 static const long long value = 1;
688};
689
690/****************************************************************************/
691/* */
692/* TypeList and its functions */
693/* */
694/****************************************************************************/
695
696template<class HEAD, class TAIL=void>
697struct TypeList
698{
699 typedef TypeList<HEAD, TAIL> type;
700 typedef HEAD Head;
701 typedef TAIL Tail;
702};
703
704template <class List, class T>
705struct Contains;
706
707template <class Head, class Tail, class T>
708struct Contains<TypeList<Head, Tail>, T>
709{
710 typedef typename Contains<Tail, T>::type type;
711};
712
713template <class Head, class Tail>
714struct Contains<TypeList<Head, Tail>, Head>
715{
716 typedef VigraTrueType type;
717};
718
719template <class T>
720struct Contains<void, T>
721{
722 typedef VigraFalseType type;
723};
724
725template <class List, class T>
726struct Remove;
727
728template <class Head, class Tail, class T>
729struct Remove<TypeList<Head, Tail>, T>
730{
731 typedef TypeList<Head, typename Remove<Tail, T>::type> type;
732};
733
734template <class Head, class Tail>
735struct Remove<TypeList<Head, Tail>, Head>
736{
737 typedef Tail type;
738};
739
740template <class T>
741struct Remove<void, T>
742{
743 typedef void type;
744};
745
746template <class A, class Tail=void>
747struct Push
748{
749 typedef TypeList<A, typename Tail::type> type;
750};
751
752template <class Head, class Tail, class List>
753struct Push<TypeList<Head, Tail>, List>
754{
755 typedef typename Push<Tail, List>::type Rest;
756 typedef TypeList<Head, Rest> type;
757};
758
759template <class Head, class Tail>
760struct Push<TypeList<Head, Tail>, void>
761{
762 typedef TypeList<Head, Tail> type;
763};
764
765template <class A>
766struct Push<A, void>
767{
768 typedef TypeList<A> type;
769};
770
771template <class A>
772struct Push<void, A>
773{
774 typedef A type;
775};
776
777template <>
778struct Push<void, void>
779{
780 typedef void type;
781};
782
783template <class A, class Tail=void>
784struct 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
790template <class Head, class Tail, class List>
791struct 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
798template <class Head, class Tail>
799struct PushUnique<TypeList<Head, Tail>, void>
800{
801 typedef TypeList<Head, Tail> type;
802};
803
804template <class A>
805struct PushUnique<A, void>
806{
807 typedef TypeList<A> type;
808};
809
810template <class A>
811struct PushUnique<void, A>
812{
813 typedef A type;
814};
815
816template <>
817struct PushUnique<void, void>
818{
819 typedef void type;
820};
821
822template <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>
826struct 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
850template <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>
854struct 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
878template <typename T0>
879inline void ignore_argument(const T0 &)
880{}
881
882template <typename T0, typename T1>
883inline void ignore_argument(const T0 &, const T1 &)
884{}
885
886template <typename T0, typename T1, typename T2>
887inline void ignore_argument(const T0 &, const T1 &, const T2 &)
888{}
889
890template <typename T0, typename T1, typename T2, typename T3>
891inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &)
892{}
893
894template <typename T0, typename T1, typename T2, typename T3, typename T4>
895inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &)
896{}
897
898template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
899inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &)
900{}
901
902template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
903inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &)
904{}
905
906template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
907inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &)
908{}
909
910template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
911inline void ignore_argument(const T0 &, const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &, const T8 &)
912{}
913
914template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
915inline 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:130
Definition: metaprogramming.hxx:116
Definition: metaprogramming.hxx:123

© 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