ICRS Eurobot 2013

Dependencies:   mbed mbed-rtos Servo QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TypePromotion.h Source File

TypePromotion.h

00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: TypePromotion.h,v 1.10 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_TYPE_PROMOTION_H
00025 #define TVMET_TYPE_PROMOTION_H
00026 
00027 namespace tvmet {
00028 
00029 
00030 /**
00031  * \class PrecisionTraits TypePromotion.h "tvmet/TypePromotion.h"
00032  * \brief Declaring ranks of types to avoid specializing
00033  *
00034  * All possible promoted types. For example, bool=1, int=2, float=3, double=4,
00035  * etc. We can use a traits class to map from a type such as float onto its
00036  * "precision rank". We will promote to whichever type has a higher
00037  * "precision rank". f there is no "precision rank" for a type, we'll
00038  * promote to whichever type requires more storage space
00039  * (and hopefully more precision).
00040  */
00041 template<class T>
00042 struct PrecisionTraits {
00043   enum {
00044     rank = 0,            /**< the rank of type. */
00045     known = 0             /**< true, if the rank is specialized = known. */
00046   };
00047 };
00048 
00049 
00050 #define TVMET_PRECISION(T,R)                          \
00051 template<>                                              \
00052 struct PrecisionTraits< T > {                            \
00053   enum {                                              \
00054     rank = R,                                       \
00055     known = 1                                       \
00056   };                                                  \
00057 };
00058 
00059 
00060 /*
00061  * pod types
00062  */
00063 TVMET_PRECISION(int, 100)
00064 TVMET_PRECISION(unsigned int, 200)
00065 TVMET_PRECISION(long, 300)
00066 TVMET_PRECISION(unsigned long, 400)
00067 
00068 #if defined(TVMET_HAVE_LONG_LONG)
00069 TVMET_PRECISION(long long, 500)
00070 TVMET_PRECISION(unsigned long long, 600)
00071 #endif // defined(TVMET_HAVE_LONG_LONG)
00072 
00073 TVMET_PRECISION(float, 700)
00074 TVMET_PRECISION(double, 800)
00075 
00076 #if defined(TVMET_HAVE_LONG_DOUBLE)
00077 TVMET_PRECISION(long double, 900)
00078 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00079 
00080 
00081 /*
00082  * complex types
00083  */
00084 #if defined(TVMET_HAVE_COMPLEX)
00085 TVMET_PRECISION(std::complex<int>, 1000)
00086 TVMET_PRECISION(std::complex<unsigned int>, 1100)
00087 TVMET_PRECISION(std::complex<long>, 1200)
00088 TVMET_PRECISION(std::complex<unsigned long>, 1300)
00089 
00090 #if defined(TVMET_HAVE_LONG_LONG)
00091 TVMET_PRECISION(std::complex<long long>, 1400)
00092 TVMET_PRECISION(std::complex<unsigned long long>, 1500)
00093 #endif // defined(TVMET_HAVE_LONG_LONG)
00094 
00095 TVMET_PRECISION(std::complex<float>, 1600)
00096 TVMET_PRECISION(std::complex<double>, 1700)
00097 
00098 #if defined(TVMET_HAVE_LONG_DOUBLE)
00099 TVMET_PRECISION(std::complex<long double>, 1800)
00100 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00101 
00102 #endif // defined(TVMET_HAVE_COMPLEX)
00103 
00104 
00105 /** \class PrecisionTraits<int>                TypePromotion.h "tvmet/TypePromotion.h" */
00106 /** \class PrecisionTraits<unsigned int>         TypePromotion.h "tvmet/TypePromotion.h" */
00107 /** \class PrecisionTraits<long>            TypePromotion.h "tvmet/TypePromotion.h" */
00108 /** \class PrecisionTraits<unsigned long>         TypePromotion.h "tvmet/TypePromotion.h" */
00109 /** \class PrecisionTraits<long long>            TypePromotion.h "tvmet/TypePromotion.h" */
00110 /** \class PrecisionTraits<unsigned long long>         TypePromotion.h "tvmet/TypePromotion.h" */
00111 /** \class PrecisionTraits<float>            TypePromotion.h "tvmet/TypePromotion.h" */
00112 /** \class PrecisionTraits<double>            TypePromotion.h "tvmet/TypePromotion.h" */
00113 /** \class PrecisionTraits<long double>            TypePromotion.h "tvmet/TypePromotion.h" */
00114 /** \class PrecisionTraits< std::complex<int> >        TypePromotion.h "tvmet/TypePromotion.h" */
00115 /** \class PrecisionTraits< std::complex<unsigned int> > TypePromotion.h "tvmet/TypePromotion.h" */
00116 /** \class PrecisionTraits< std::complex<long> >    TypePromotion.h "tvmet/TypePromotion.h" */
00117 /** \class PrecisionTraits< std::complex<unsigned long> > TypePromotion.h "tvmet/TypePromotion.h" */
00118 /** \class PrecisionTraits< std::complex<long long> >    TypePromotion.h "tvmet/TypePromotion.h" */
00119 /** \class PrecisionTraits< std::complex<unsigned long long> > TypePromotion.h "tvmet/TypePromotion.h" */
00120 /** \class PrecisionTraits< std::complex<float> >    TypePromotion.h "tvmet/TypePromotion.h" */
00121 /** \class PrecisionTraits< std::complex<double> >    TypePromotion.h "tvmet/TypePromotion.h" */
00122 /** \class PrecisionTraits< std::complex<long double> >    TypePromotion.h "tvmet/TypePromotion.h" */
00123 
00124 #undef TVMET_PRECISION
00125 
00126 
00127 /**
00128  * \class AutopromoteTraits TypePromotion.h "tvmet/TypePromotion.h"
00129  * \brief The promoted types traits.
00130  */
00131 template<class T>
00132 struct AutopromoteTraits {
00133   typedef T value_type;
00134 };
00135 
00136 
00137 /*
00138  * Defines a macro for specializing/defining
00139  * the promotion traits. bool, char, unsigned char, short int, etc. will
00140  * be autopromote to int, as in C and C++.
00141  */
00142 #define TVMET_AUTOPROMOTE(T1,T2)                       \
00143 template<>                                               \
00144 struct AutopromoteTraits<T1> {                         \
00145   typedef T2 value_type;                              \
00146 };
00147 
00148 TVMET_AUTOPROMOTE(bool, int)
00149 TVMET_AUTOPROMOTE(char, int)
00150 TVMET_AUTOPROMOTE(unsigned char, int)
00151 TVMET_AUTOPROMOTE(short int, int)
00152 TVMET_AUTOPROMOTE(short unsigned int, unsigned int)
00153 
00154 /** \class AutopromoteTraits<bool>    TypePromotion.h "tvmet/TypePromotion.h" */
00155 /** \class AutopromoteTraits<char>    TypePromotion.h "tvmet/TypePromotion.h" */
00156 /** \class AutopromoteTraits<unsigned char> TypePromotion.h "tvmet/TypePromotion.h" */
00157 /** \class AutopromoteTraits<short int>    TypePromotion.h "tvmet/TypePromotion.h" */
00158 /** \class AutopromoteTraits<short unsigned int> TypePromotion.h "tvmet/TypePromotion.h" */
00159 
00160 #undef TVMET_AUTOPROMOTE
00161 
00162 
00163 /**
00164  * \class promoteTo TypePromotion.h "tvmet/TypePromotion.h"
00165  * \brief Promote to T1.
00166  */
00167 template<class T1, class T2, int promoteToT1>
00168 struct promoteTo {
00169   typedef T1 value_type;
00170 };
00171 
00172 
00173 /**
00174  * \class promoteTo<T1,T2,0> TypePromotion.h "tvmet/TypePromotion.h"
00175  * \brief Promote to T2
00176  */
00177 template<class T1, class T2>
00178 struct promoteTo<T1,T2,0> {
00179   typedef T2 value_type;
00180 };
00181 
00182 
00183 /**
00184  * \class PromoteTraits TypePromotion.h "tvmet/TypePromotion.h"
00185  * \brief Promote type traits
00186  */
00187 template<class T1org, class T2org>
00188 class PromoteTraits {
00189   // Handle promotion of small integers to int/unsigned int
00190   typedef typename AutopromoteTraits<T1org>::value_type T1;
00191   typedef typename AutopromoteTraits<T2org>::value_type T2;
00192 
00193   enum {
00194     // True if T1 is higher ranked
00195     T1IsBetter = int(PrecisionTraits<T1>::rank) > int(PrecisionTraits<T2>::rank),
00196 
00197     // True if we know ranks for both T1 and T2
00198     knowBothRanks = PrecisionTraits<T1>::known && PrecisionTraits<T2>::known,
00199 
00200     // True if we know T1 but not T2
00201     knowT1butNotT2 = PrecisionTraits<T1>::known && !(PrecisionTraits<T2>::known),
00202 
00203     // True if we know T2 but not T1
00204     knowT2butNotT1 =  PrecisionTraits<T2>::known && !(PrecisionTraits<T1>::known),
00205 
00206     // True if T1 is bigger than T2
00207     T1IsLarger = sizeof(T1) >= sizeof(T2),
00208 
00209     // We know T1 but not T2: true
00210     // We know T2 but not T1: false
00211     // Otherwise, if T1 is bigger than T2: true
00212     defaultPromotion = knowT1butNotT2 ? false : (knowT2butNotT1 ? true : T1IsLarger),
00213 
00214     // If we have both ranks, then use them.
00215     // If we have only one rank, then use the unknown type.
00216     // If we have neither rank, then promote to the larger type.
00217     promoteToT1 = (knowBothRanks ? T1IsBetter : defaultPromotion) ? 1 : 0
00218   };
00219 
00220  public:
00221   typedef typename promoteTo<T1,T2,promoteToT1>::value_type value_type;
00222 };
00223 
00224 
00225 } // namespace tvmet
00226 
00227 #endif // TVMET_TYPE_PROMOTION_H
00228 
00229 // Local Variables:
00230 // mode:C++
00231 // tab-width:8
00232 // End: