[ 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.0 (Thu Aug 25 2011)