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

vigra/metaprogramming.hxx |

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*                                                                      */
    00005 /*    This file is part of the VIGRA computer vision library.           */
    00006 /*    The VIGRA Website is                                              */
    00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
    00008 /*    Please direct questions, bug reports, and contributions to        */
    00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00010 /*        vigra@informatik.uni-hamburg.de                               */
    00011 /*                                                                      */
    00012 /*    Permission is hereby granted, free of charge, to any person       */
    00013 /*    obtaining a copy of this software and associated documentation    */
    00014 /*    files (the "Software"), to deal in the Software without           */
    00015 /*    restriction, including without limitation the rights to use,      */
    00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00017 /*    sell copies of the Software, and to permit persons to whom the    */
    00018 /*    Software is furnished to do so, subject to the following          */
    00019 /*    conditions:                                                       */
    00020 /*                                                                      */
    00021 /*    The above copyright notice and this permission notice shall be    */
    00022 /*    included in all copies or substantial portions of the             */
    00023 /*    Software.                                                         */
    00024 /*                                                                      */
    00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00033 /*                                                                      */
    00034 /************************************************************************/
    00035
    00036 #ifndef VIGRA_METAPROGRAMMING_HXX
    00037 #define VIGRA_METAPROGRAMMING_HXX
    00038
    00039 #include "config.hxx"
    00040 #include <climits>
    00041 #include <limits>
    00042
    00043 namespace vigra {
    00044
    00045 template <int N>
    00046 class MetaInt
    00047 {
    00048   public:
    00049     static const int value = N;
    00050 };
    00051
    00052 template <int N1, int N2>
    00053 class MetaMax
    00054 {
    00055   public:
    00056     static const int value = N1 < N2 ? N2 : N1;
    00057 };
    00058
    00059 template <int N1, int N2>
    00060 class MetaMin
    00061 {
    00062   public:
    00063     static const int value = N1 < N2 ? N1 : N2;
    00064 };
    00065
    00066 struct VigraTrueType
    00067 {
    00068    static const bool asBool = true, value = true;
    00069 };
    00070
    00071 struct VigraFalseType
    00072 {
    00073     static const bool asBool = false, value = false;
    00074 };
    00075
    00076 /**  \addtogroup MultiArrayTags Multi-dimensional Array Tags
    00077       Meta-programming tags to mark array's as strided or unstrided.
    00078 */
    00079
    00080 //@{
    00081
    00082 /********************************************************/
    00083 /*                                                      */
    00084 /*                   StridedArrayTag                    */
    00085 /*                                                      */
    00086 /********************************************************/
    00087
    00088 /** tag for marking a MultiArray strided.
    00089
    00090 <b>\#include</b>
    00091 <<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>>
    00092
    00093 Namespace: vigra
    00094 */
    00095 struct StridedArrayTag {};
    00096
    00097 /********************************************************/
    00098 /*                                                      */
    00099 /*                  UnstridedArrayTag                   */
    00100 /*                                                      */
    00101 /********************************************************/
    00102
    00103 /** tag for marking a MultiArray unstrided.
    00104
    00105 <b>\#include</b>
    00106 <<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>>
    00107
    00108 Namespace: vigra
    00109 */
    00110 struct UnstridedArrayTag {};
    00111
    00112 template<class T>
    00113 class TypeTraits
    00114 {
    00115   public:
    00116     typedef VigraFalseType isConst;
    00117     typedef VigraFalseType isPOD;
    00118     typedef VigraFalseType isBuiltinType;
    00119 };
    00120
    00121 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00122
    00123 template<class T>
    00124 class TypeTraits<T const>
    00125 : public TypeTraits<T>
    00126 {
    00127   public:
    00128     typedef VigraTrueType isConst;
    00129 };
    00130
    00131 template<class T>
    00132 class TypeTraits<T *>
    00133 {
    00134   public:
    00135     typedef VigraFalseType isConst;
    00136     typedef VigraTrueType isPOD;
    00137     typedef VigraTrueType isBuiltinType;
    00138 };
    00139
    00140 template<class T>
    00141 class TypeTraits<T const *>
    00142 {
    00143   public:
    00144     typedef VigraFalseType isConst;
    00145     typedef VigraTrueType isPOD;
    00146     typedef VigraTrueType isBuiltinType;
    00147 };
    00148
    00149 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00150
    00151 namespace detail {
    00152
    00153 template <int size>
    00154 struct SizeToType;
    00155
    00156 } // namespace detail
    00157
    00158 #define VIGRA_TYPE_TRAITS(type, size) \
    00159 template<> \
    00160 class TypeTraits<type> \
    00161 { \
    00162   public: \
    00163     typedef VigraFalseType isConst; \
    00164     typedef VigraTrueType isPOD; \
    00165     typedef VigraTrueType isBuiltinType; \
    00166     typedef char TypeToSize[size]; \
    00167 }; \
    00168  \
    00169 namespace detail { \
    00170   TypeTraits<type>::TypeToSize * typeToSize(type); \
    00171   \
    00172   template <> \
    00173   struct SizeToType<size> \
    00174   { \
    00175       typedef type result; \
    00176   }; \
    00177 }
    00178
    00179 VIGRA_TYPE_TRAITS(char, 1)
    00180 VIGRA_TYPE_TRAITS(signed char, 2)
    00181 VIGRA_TYPE_TRAITS(unsigned char, 3)
    00182 VIGRA_TYPE_TRAITS(short, 4)
    00183 VIGRA_TYPE_TRAITS(unsigned short, 5)
    00184 VIGRA_TYPE_TRAITS(int, 6)
    00185 VIGRA_TYPE_TRAITS(unsigned int, 7)
    00186 VIGRA_TYPE_TRAITS(long, 8)
    00187 VIGRA_TYPE_TRAITS(unsigned long, 9)
    00188 VIGRA_TYPE_TRAITS(float, 10)
    00189 VIGRA_TYPE_TRAITS(double, 11)
    00190 VIGRA_TYPE_TRAITS(long double, 12)
    00191 #ifdef LLONG_MAX
    00192 VIGRA_TYPE_TRAITS(long long, 13)
    00193 VIGRA_TYPE_TRAITS(unsigned long long, 14)
    00194 #endif
    00195
    00196 #undef VIGRA_TYPE_TRAITS
    00197
    00198 //@}
    00199
    00200 template <class A>
    00201 struct Not;
    00202
    00203 template <>
    00204 struct Not<VigraTrueType>
    00205 {
    00206     typedef VigraFalseType result;        // deprecated
    00207     static const bool boolResult = false; // deprecated
    00208     typedef VigraFalseType type;
    00209     static const bool value = false;
    00210 };
    00211
    00212 template <>
    00213 struct Not<VigraFalseType>
    00214 {
    00215     typedef VigraTrueType result;        // deprecated
    00216     static const bool boolResult = true; // deprecated
    00217     typedef VigraTrueType type;
    00218     static const bool value = true;
    00219 };
    00220
    00221 template <class L, class R>
    00222 struct And;
    00223
    00224 template <>
    00225 struct And<VigraFalseType, VigraFalseType>
    00226 {
    00227     typedef VigraFalseType result;        // deprecated
    00228     static const bool boolResult = false; // deprecated
    00229     typedef VigraFalseType type;
    00230     static const bool value = false;
    00231 };
    00232
    00233 template <>
    00234 struct And<VigraFalseType, VigraTrueType>
    00235 {
    00236     typedef VigraFalseType result;        // deprecated
    00237     static const bool boolResult = false; // deprecated
    00238     typedef VigraFalseType type;
    00239     static const bool value = false;
    00240 };
    00241
    00242 template <>
    00243 struct And<VigraTrueType, VigraFalseType>
    00244 {
    00245     typedef VigraFalseType result;        // deprecated
    00246     static const bool boolResult = false; // deprecated
    00247     typedef VigraFalseType type;
    00248     static const bool value = false;
    00249 };
    00250
    00251 template <>
    00252 struct And<VigraTrueType, VigraTrueType>
    00253 {
    00254     typedef VigraTrueType result;        // deprecated
    00255     static const bool boolResult = true; // deprecated
    00256     typedef VigraTrueType type;
    00257     static const bool value = true;
    00258 };
    00259
    00260 template <class L, class R>
    00261 struct Or;
    00262
    00263 template <>
    00264 struct Or<VigraFalseType, VigraFalseType>
    00265 {
    00266     typedef VigraFalseType result;        // deprecated
    00267     static const bool boolResult = false; // deprecated
    00268     typedef VigraFalseType type;
    00269     static const bool value = false;
    00270 };
    00271
    00272 template <>
    00273 struct Or<VigraTrueType, VigraFalseType>
    00274 {
    00275     typedef VigraTrueType result;        // deprecated
    00276     static const bool boolResult = true; // deprecated
    00277     typedef VigraTrueType type;
    00278     static const bool value = true;
    00279 };
    00280
    00281 template <>
    00282 struct Or<VigraFalseType, VigraTrueType>
    00283 {
    00284     typedef VigraTrueType result;        // deprecated
    00285     static const bool boolResult = true; // deprecated
    00286     typedef VigraTrueType type;
    00287     static const bool value = true;
    00288 };
    00289
    00290 template <>
    00291 struct Or<VigraTrueType, VigraTrueType>
    00292 {
    00293     typedef VigraTrueType result;        // deprecated
    00294     static const bool boolResult = true; // deprecated
    00295     typedef VigraTrueType type;
    00296     static const bool value = true;
    00297 };
    00298
    00299 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00300
    00301 template <class PREDICATE, class TRUECASE, class FALSECASE>
    00302 struct If;
    00303
    00304 template <class TRUECASE, class FALSECASE>
    00305 struct If<VigraTrueType, TRUECASE, FALSECASE>
    00306 {
    00307     typedef TRUECASE type;
    00308 };
    00309
    00310 template <class TRUECASE, class FALSECASE>
    00311 struct If<VigraFalseType, TRUECASE, FALSECASE>
    00312 {
    00313     typedef FALSECASE type;
    00314 };
    00315
    00316 template <bool PREDICATE, class TRUECASE, class FALSECASE>
    00317 struct IfBool;
    00318
    00319 template <class TRUECASE, class FALSECASE>
    00320 struct IfBool<true, TRUECASE, FALSECASE>
    00321 {
    00322     typedef TRUECASE type;
    00323 };
    00324
    00325 template <class TRUECASE, class FALSECASE>
    00326 struct IfBool<false, TRUECASE, FALSECASE>
    00327 {
    00328     typedef FALSECASE type;
    00329 };
    00330
    00331 template <class L, class R>
    00332 struct IsSameType
    00333 {
    00334     typedef VigraFalseType result;        // deprecated
    00335     static const bool boolResult = false; // deprecated
    00336     typedef VigraFalseType type;
    00337     static const bool value = false;
    00338 };
    00339
    00340 template <class T>
    00341 struct IsSameType<T, T>
    00342 {
    00343     typedef VigraTrueType result;        // deprecated
    00344     static const bool boolResult = true; // deprecated
    00345     typedef VigraTrueType type;
    00346     static const bool value = true;
    00347 };
    00348
    00349 template <class L, class R>
    00350 struct IsDifferentType
    00351 {
    00352     typedef VigraTrueType type;
    00353     static const bool value = true;
    00354 };
    00355
    00356 template <class T>
    00357 struct IsDifferentType<T, T>
    00358 {
    00359     typedef VigraFalseType type;
    00360     static const bool value = false;
    00361 };
    00362
    00363 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00364
    00365 template <class From, class To>
    00366 struct IsConvertibleTo
    00367 {
    00368     typedef char falseResult[1];
    00369     typedef char trueResult[2];
    00370
    00371     static From const & check();
    00372
    00373     static falseResult * testIsConvertible(...);
    00374     static trueResult * testIsConvertible(To const &);
    00375
    00376     enum { resultSize = sizeof(*testIsConvertible(check())) };
    00377
    00378     static const bool value = (resultSize == 2);
    00379     typedef typename
    00380         IfBool<value, VigraTrueType, VigraFalseType>::type
    00381         type;
    00382 };
    00383
    00384 template <class DERIVED, class BASE>
    00385 struct IsDerivedFrom
    00386 {
    00387     typedef char falseResult[1];
    00388     typedef char trueResult[2];
    00389
    00390     static falseResult * testIsDerivedFrom(...);
    00391     static trueResult * testIsDerivedFrom(BASE const *);
    00392
    00393     enum { resultSize = sizeof(*testIsDerivedFrom((DERIVED const *)0)) };
    00394
    00395     static const bool value = (resultSize == 2);
    00396     typedef typename
    00397         IfBool<value, VigraTrueType, VigraFalseType>::type
    00398         type;
    00399
    00400     static const bool boolResult = value; // deprecated
    00401     typedef type result;                  // deprecated
    00402 };
    00403
    00404 template <class T>
    00405 struct UnqualifiedType
    00406 {
    00407     typedef T type;
    00408 };
    00409
    00410 template <class T>
    00411 struct UnqualifiedType<T const>
    00412 {
    00413     typedef T type;
    00414 };
    00415
    00416 template <class T>
    00417 struct UnqualifiedType<T &>
    00418 : public UnqualifiedType<T>
    00419 {};
    00420
    00421 template <class T>
    00422 struct UnqualifiedType<T const &>
    00423 : public UnqualifiedType<T>
    00424 {};
    00425
    00426 template <class T>
    00427 struct UnqualifiedType<T *>
    00428 : public UnqualifiedType<T>
    00429 {};
    00430
    00431 template <class T>
    00432 struct UnqualifiedType<T const *>
    00433 : public UnqualifiedType<T>
    00434 {};
    00435
    00436
    00437 template <class T>
    00438 struct has_result_type
    00439 {
    00440     typedef char falseResult[1];
    00441     typedef char trueResult[2];
    00442
    00443     static falseResult * test(...);
    00444     template <class U>
    00445     static trueResult * test(U *, typename U::result_type * = 0);
    00446
    00447     enum { resultSize = sizeof(*test((T*)0)) };
    00448
    00449     static const bool value = (resultSize == 2);
    00450     typedef typename
    00451         IfBool<value, VigraTrueType, VigraFalseType>::type
    00452         type;
    00453 };
    00454
    00455 template <class T>
    00456 struct has_value_type
    00457 {
    00458     typedef char falseResult[1];
    00459     typedef char trueResult[2];
    00460
    00461     static falseResult * test(...);
    00462     template <class U>
    00463     static trueResult * test(U *, typename U::value_type * = 0);
    00464
    00465     enum { resultSize = sizeof(*test((T*)0)) };
    00466
    00467     static const bool value = (resultSize == 2);
    00468     typedef typename
    00469         IfBool<value, VigraTrueType, VigraFalseType>::type
    00470         type;
    00471 };
    00472
    00473 template <class T>
    00474 struct IsIterator
    00475 {
    00476     typedef char falseResult[1];
    00477     typedef char trueResult[2];
    00478
    00479     static falseResult * test(...);
    00480     template <class U>
    00481     static trueResult * test(U *, typename U::iterator_category * = 0);
    00482
    00483     enum { resultSize = sizeof(*test((T*)0)) };
    00484
    00485     static const bool value = (resultSize == 2);
    00486     typedef typename
    00487         IfBool<value, VigraTrueType, VigraFalseType>::type
    00488         type;
    00489 };
    00490
    00491 template <class T>
    00492 struct IsIterator<T*>
    00493 {
    00494     static const bool value = true;
    00495     typedef VigraTrueType type;
    00496 };
    00497
    00498 template <class T>
    00499 struct IsIterator<T const *>
    00500 {
    00501     static const bool value = true;
    00502     typedef VigraTrueType type;
    00503 };
    00504
    00505 } // namespace vigra
    00506
    00507 #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.7.1 (3 Dec 2010)